使用Pandas和Matplotlib绘制2个堆叠序列

2024-10-03 11:26:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我拼命想用Matplot创建漂亮的图形,但这不是一件容易的事。具体来说,我有两个系列(serie1serie2)。对于每个

我有3组(第1组、第2组和第3组)。对于每个小组,我都有一些主题和价值观。每个系列通过不同的变量(主题)描述几个个体(G1、G2、G3)的行为。代码是:

import pandas as pd
d = {"ThemeA": [25,34,75], "ThemeB": [0,71,18], "ThemeC": [2,0,0], "ThemeD":[1,14,0] }
serie1 = pd.DataFrame(data = d, index=["Groupe 1", "Groupe 2", "Groupe 3"] )
serie1= serie1.loc[:,:].div(serie1.sum(1), axis=0) * 100

d = {"ThemeA": [145,10,3], "ThemeB": [10,1,70], "ThemeC": [34,1,2], "ThemeD":[3,17,27]}
serie2= pd.DataFrame(data = d, index=["Groupe 1", "Groupe 2", "Groupe 3"])
serie2= serie2.loc[:,:].div(serie2.sum(1), axis=0) * 100

现在我想制作一个图表来显示用户数据:

ax = fig.add_subplot(111) 
ax = serie1.plot(kind='barh', ax=ax, width=0.2, stacked=True, position=0, sharex=True, 
             sharey=True, legend=True, figsize = (6,2))

serie2.plot(kind='barh', ax=ax, width=0.2, stacked=True, position=1.6, 
               sharex=True, sharey=True, legend=False)
ax.grid(False)
plt.ylim([-0.5, 2.5])

我得到了以下图表:

Badddd

但我想把这个传说移到最底层。如果我想这么做

ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05), 
           fancybox=True, shadow=True, ncol=5)

我得到以下输出,它有太多的标签

Arrrrrrrrggg

当然,我希望每个标签在图例中只显示一次。
如果有人有奇迹般的解决办法,我就是一个接受者!提前谢谢


Tags: truedataframe主题dataaxlocpdlegend
2条回答

您可以使用比需要更长的xaxis来为图例留出空白

# calculate the size of the longer column (max of row sums)
max_col = serie2.sum(axis=1).max()
# increase the size of the x axis a factor of 1.4
xlim(0, max_col*1.4)

如果您想在底部显示图例,那么在调用legend时,实际上是从两个绘图中绘制标签。您需要删除重复的标签。为此你要用字典

from collections import OrderedDict

fig = figure()
figsize(6,2)
ax = fig.add_subplot(111) 

serie1.plot(kind='barh', ax=ax, width=0.2, stacked=True, position=0,
            sharex=True, sharey=True)

serie2.plot(kind='barh', ax=ax, width=0.2, stacked=True, position=1.6, 
            sharex=True, sharey=True)

handles, labels = gca().get_legend_handles_labels()
my_labels = OrderedDict(zip(labels, handles))
legend(my_labels.values(), my_labels.keys(), loc='upper center',
       bbox_to_anchor=(0.5, -0.1), fancybox=True, shadow=True, ncol=5)

ax.grid(False)
ylim([-0.5, 2.5])

然后你会得到:

enter image description here

在这种情况下,一个单行的方法是添加行

serie2.columns= ["_" + col for col in serie2.columns]

在绘制第二个数据帧之前。这将用下划线替换所有列名,后跟原始名称。由于以下划线("_")开头的名称不会显示在图例中,因此只剩下第一个数据帧的图例项。
此解决方案要求两个数据帧中的列顺序相同

相关问题 更多 >