dubbbdan dubbbdan - 1 month ago 7
Python Question

Two Y axis Bar plot: custom xticks

I am trying to add custom xticks to a relatively complicated bar graph plot and I am stuck.

I am plotting from two data frames,

merged_90
and
merged_15
:

merged_15
Volume y_err_x Area_2D y_err_y
TripDate
2015-09-22 1663.016032 199.507503 1581.591701 163.473202

merged_90

Volume y_err_x Area_2D y_err_y
TripDate
1990-06-10 1096.530711 197.377497 1531.651913 205.197493


I want to create a bar graph with two axes (i.e.
Area_2D
and
Volume
) where the
Area_2D
and
Volume
bars are grouped based on their respective data frame. An example script would look like:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy


fig = plt.figure()
ax1 = fig.add_subplot(111)
merged_90.Volume.plot(ax=ax1, color='orange', kind='bar',position=2.5, yerr=merged_90['y_err_x'] ,use_index=False , width=0.1)
merged_15.Volume.plot(ax=ax1, color='red', kind='bar',position=0.9, yerr=merged_15['y_err_x'] ,use_index=False, width=0.1)


ax2 = ax1.twinx()
merged_90.Area_2D.plot(ax=ax2,color='green', kind='bar',position=3.5, yerr=merged_90['y_err_y'],use_index=False, width=0.1)
merged_15.Area_2D.plot(ax=ax2,color='blue', kind='bar',position=0, yerr=merged_15['y_err_y'],use_index=False, width=0.1)

ax1.set_xlim(-0.5,0.2)

x = scipy.arange(1)
ax2.set_xticks(x)
ax2.set_xticklabels(['2015'])
plt.tight_layout()
plt.show()


The resulting plot is:

Plot missing xtick

One would think I could change:

x = scipy.arange(1)
ax2.set_xticks(x)
ax2.set_xticklabels(['2015'])


to

x = scipy.arange(2)
ax2.set_xticks(x)
ax2.set_xticklabels(['1990','2015'])


but that results in:

Disorganized plot

I would like to see the ticks ordered in chronological order (i.e. 1990,2015)

Thanks!

Grr Grr
Answer

Have you considered dropping the second axis and plotting them as follows:

ind = np.array([0,0.3])
width = 0.1
fig, ax = plt.subplots()
Rects1 = ax.bar(ind, [merged_90.Volume.values, merged_15.Volume.values], color=['orange', 'red'] ,width=width)
Rects2 = ax.bar(ind + width, [merged_90.Area_2D.values, merged_15.Area_2D.values], color=['green', 'blue'] ,width=width)
ax.set_xticks([.1,.4]) 
ax.set_xticklabels(('1990','2015'))

This produces:

enter image description here

I omitted the error and colors but you can easily add them. That would produce a readable graph given your test data. As you mentioned in comments you would still rather have two axes, presumably for different data with proper scales. To do this you could do: fig = plt.figure() ax1 = fig.add_subplot(111) merged_90.Volume.plot(ax=ax, color='orange', kind='bar',position=2.5, use_index=False , width=0.1) merged_15.Volume.plot(ax=ax, color='red', kind='bar',position=1.0, use_index=False, width=0.1) ax2 = ax1.twinx() merged_90.Area_2D.plot(ax=ax,color='green', kind='bar',position=3.5,use_index=False, width=0.1) merged_15.Area_2D.plot(ax=ax,color='blue', kind='bar',position=0,use_index=False, width=0.1) ax1.set_xlim([-.45, .2]) ax2.set_xlim(-.45, .2]) ax1.set_xticks([-.35, 0]) ax1.set_xticklabels([1990, 2015])

This produces: enter image description here

Your problem was with resetting just one axis limit and not the other, they are created as twins but do not necessarily follow the changes made to one another.

Comments