我想知道在使用大熊猫提供的绘图时,是否有办法在条形图中居中重叠。
当使用twiny时,我们得到与不同图对应的条重叠,这是非常实用的。当它们具有相同的宽度时,它们将完全相互对齐。
然而,当一个人改变其中一个集合的宽度时,它们将不再居中,这使得情节看起来很混乱,如下所示:
猫1和猫2的第一个黑条完全以相应的蓝条为中心。然而,下一个黑条不在橙色条的中心,与第三个黑条不在绿色条的中心。
从这里可以看出,当它们具有相同的宽度时,它们完全居中。那么当它们没有相同的宽度时,它们如何以相同的方式居中?:
这是创建当前未中心情节的代码:
from io import StringIO
import pandas as pd
import matplotlib.pyplot as plt
txt = '''Category COLUMN1 COLUMN2 COLUMN3
A 0.5 3 Cat1
B 0.3 5 Cat1
C 0.7 4 Cat1
A 0.4 3 Cat2
B 0.8 5 Cat2
C 0.3 4 Cat2
'''
df = pd.read_table(StringIO(txt), sep="\s+")
order = ['Cat1', 'Cat2']
fig, ax = plt.subplots()
ax2 = ax.twiny()
col1 = pd.pivot_table(df,index='COLUMN3',columns='Category',values='COLUMN1').reindex(order)
col1.plot(kind='bar', ax=ax, edgecolor='Black', lw=1, color='black')
col2 = pd.pivot_table(df,index='COLUMN3',columns='Category',values='COLUMN2').reindex(order)
col2.plot(kind='bar', ax=ax2, legend=False, alpha=0.7)
ax2.xaxis.set_visible(False)
plt.show()
修改
这是一张想要的图片,请原谅“糟糕的图形编辑”。:
答案 0 :(得分:2)
首先,您需要使用相同比例的条形位置和宽度。因此,您可能希望创建twinx
轴而不是twiny
。 (您仍然可以使用ax.set_ylim(ax2.get_ylim())
来使y比例相等。)
然后,如果主轴上的杆数与双轴中的杆数一样多,我们就会有一对一的对应关系,并且可以计算出黑条“'位置取决于彩色条'位置。
for bbar, cbar in zip(ax.patches, ax2.patches):
cpos = cbar.get_x()+cbar.get_width()/2.
bpos = cpos-bbar.get_width()/2.
bbar.set_x(bpos)
完整的代码,产生上述情节:
from io import StringIO
import pandas as pd
import matplotlib.pyplot as plt
txt = u'''Category COLUMN1 COLUMN2 COLUMN3
A 0.5 3 Cat1
B 0.3 5 Cat1
C 0.7 4 Cat1
A 0.4 3 Cat2
B 0.8 5 Cat2
C 0.3 4 Cat2
'''
df = pd.read_table(StringIO(txt), sep="\s+")
order = ['Cat1', 'Cat2']
fig, ax = plt.subplots()
ax2 = ax.twinx()
col1 = pd.pivot_table(df,index='COLUMN3',columns='Category',values='COLUMN1').reindex(order)
col1.plot(kind='bar', ax=ax, edgecolor='Black', lw=1, color='black', width=0.2)
col2 = pd.pivot_table(df,index='COLUMN3',columns='Category',values='COLUMN2').reindex(order)
col2.plot(kind='bar', ax=ax2, legend=False, alpha=0.7)
ax2.xaxis.set_visible(False)
ax.set_ylim(ax2.get_ylim())
for bbar, cbar in zip(ax.patches, ax2.patches):
cpos = cbar.get_x()+cbar.get_width()/2.
bpos = cpos-bbar.get_width()/2.
bbar.set_x(bpos)
plt.show()