Reputation:
I'm trying to create a bar graph with 2 bars on one X axis tick(date) that represents two sets of data. However, I'm not able to make it span across the the graph to other x axis ticks.
Here is my code:
simsubs = pd.read_csv('simsubs.csv')
fig, axs = plt.subplots(4, sharex=True, figsize=(11,9))
bar_width = 0.35
x = simsubs.Date
axs[3].bar(x, simsubs['CPS1 Deletes'], width=bar_width, zorder=2, label='Deletes', color='#A31214')
axs[3].bar(bar_width, simsubs['CPS1 Total'], width=bar_width, zorder=2, label='Deletes', color='blue')
plt.xticks(rotation=45)
plt.show()
simsubs.Date
points to dates in my CSV that I would like plotted along the X axis but this is the img my code produces:
Thanks in advance for any help. I'm new to the community and python coding in general, apologies if my terminology or my post might be confusing.
Upvotes: 1
Views: 205
Reputation: 10590
You need to create your bar graphs on the same scale. An easy way is to create x values that simply count the data and offset them appropriately. You can label the x axis with set_xticklabels
if you want.
X = np.arange(len(x))
bar_width = 0.25
offset = bar_width / 2
axs[3].bar(X - offset, simsubs['CPS1 Deletes'], width=bar_width, color='#A31214')
axs[3].bar(X + offset, simsubs['CPS1 Total'], width=bar_width, color='blue')
axs[3].set_xticks(X)
axs[3].set_xticklabels(x)
Also having zorder
and label
the same for both calls to bar
defeats their intended use if these are the only data you are plotting.
Alternatively, you can use pandas plotting:
simsubs[['CPS1 Deletes', 'CPS1 Total']].plot.bar()
Upvotes: 1
Reputation: 4275
axs[3].bar(bar_width, simsubs['CPS1 Total'], width=bar_width, zorder=2, label='Deletes', color='blue')
Here your x value is stationary, i.e. all data is plotted on x = bar_width = 0.35
. You should change bar_width to x + bar_width (i.e. offset x position of second bar plot by bar_width from the first one) so it looks like this:
axs[3].bar(x + bar_width, simsubs['CPS1 Total'], width=bar_width, zorder=2, label='Deletes', color='blue')
Edit:
Seeing as your x values are Timestamps, I manage to do what you're looking for by first changing those Timestamp values to pandas DateTime object as:
simsubs['Date'] = simsubs['Date'].apply(pd.to_datetime)
then applying an offset which you would have to adjust as:
x_offset = simsubs['Date'] + pd.Timedelta(offset, units)
This should work as your X values are evenly distributed (7 days apart) and so I would suggest offset = 3.5
and units = 'days'
. Use this x_offset as x value in your second bar plot.
I've tried resetting these DateTime objects to TimeStamps (in case dates are NOT evenly distributed, it looks better with TimeStamps), but plotting keeps messing up for me.
Upvotes: 0