2

Pandas offers a nice, simple way to plot a (vertical) bar chart on two y axes. Is there an equivalent for the horizontal bar chart?

To adapt from the linked example:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO
s = StringIO("""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")
df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)

_ = df.plot( kind= 'barh' , secondary_y= 'amount' , rot= 0 ) 
# Doesn't work as expected. And there's no secondary_x.

plt.show()
bongbang
  • 1,610
  • 4
  • 18
  • 34

2 Answers2

1

Not quite the same as what you're asking:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO
s = StringIO("""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")
df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)

ax = df['price'].plot.barh(color='blue', alpha=.5) 
ax2 = ax.twiny()
df['amount'].plot.barh(ax=ax2, color='yellow', alpha =.5 )
plt.show()

Output:

enter image description here

Scott Boston
  • 147,308
  • 15
  • 139
  • 187
0

The short answer to your question is that no, there is no equivalent of secondary_y for barh plots in pandas, as testimonied by this issue in Pandas which is still open.

This is how I managed to get the desired effect. You'll have to figure out a scale factor yourself, and use the twiny ax functionality of matplotlib.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO
s = StringIO("""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")
df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)
fig, ax = plt.subplots(figsize=(10,5))

y_pos = np.arange(len(df))
scale_factor = 100
ax.barh(y_pos, df.amount, align='edge', height=0.4, label='amount (top)')
ax.barh(y_pos, df.price/scale_factor, align='edge', height=-0.4, label='price')
ax.set_yticks(y_pos)
ax.set_yticklabels(df.index)
ax.set_xlabel('Price')
ax.legend()

ax2 = ax.twiny()
ax2.set_xticks(ax.get_xticks())
ax2.set_xbound(ax.get_xbound())
ax2.set_xticklabels([int(x*scale_factor) for x in ax.get_xticks()])
ax2.set_xlabel('Amount')

plt.show()

Output:

Example of double axis in horizontal bar charts

Ruggero
  • 170
  • 1
  • 7