【问题标题】:How to create a single legend for a group of bar charts generated from a dataframe如何为从数据框生成的一组条形图创建单个图例
【发布时间】:2019-04-18 22:45:06
【问题描述】:

我有一个如代码所示的数据框,我使用循环为每一行生成了一个条形图。我正在尝试为右下角的所有图表绘制一个图例,但没有成功。我尝试了以下代码行 - 以及在网上找到的许多其他代码 - 在绘图循环内部和外部都没有成功。请提出可行的解决方案。

#handles, labels = bars.get_legend_handles_labels()    
#bars.legend(handles, labels)
#bars.legend(loc='bottom right', ncol=9)




import pandas as pd
import matplotlib.pyplot as plt
import io

lines=['Business Category,Not_sure!,Performance_of_certain_applications,DNS_Resolution_Time,User’s_perception_of_your_network_(QoE),Routing_stability,Packet_loss/Jitter,Network_utilisation,Reachability,Latency,Bandwidth/Throughput\n'
'Academic 
Institution,0.0,18.0,16.0,19.0,17.0,17.0,22.0,24.0,26.0,33.0\n'
'Civil society,0.0,5.0,2.0,2.0,1.0,1.0,2.0,4.0,4.0,6.0\n'
'End-user (Home/Mobile broadband),0.0,5.0,7.0,5.0,5.0,6.0,7.0,6.0,9.0,9.0\n'
'Internet Service Provider (ISP),1.0,20.0,22.0,22.0,27.0,31.0,20.0,25.0,32.0,32.0\n'
'Internet eXchange Point (IXP),0.0,2.0,3.0,2.0,7.0,6.0,5.0,5.0,8.0,7.0\n'
'Other,1.0,7.0,8.0,9.0,10.0,9.0,17.0,13.0,16.0,19.0\n'
'Regulator/Government Agency,0.0,1.0,1.0,2.0,1.0,0.0,2.0,1.0,4.0,5.0\n'
'Total,2.0,58.0,59.0,61.0,68.0,70.0,75.0,78.0,99.0,111.0\n']
df3 = pd.read_csv(pd.compat.StringIO("\n".join(lines)), sep=",").set_index('Business Category')

i = j = roundcounter = 0
patterns = ['\\', '|', '/', '+', 'x', 'o', 'O', '.', '*', '-']
color=['orange', 'darkseagreen', 'maroon', 'mediumpurple', 'saddlebrown', 'orchid', 'indianred',
      'tomato', 'dimgrey', 'aquamarine'] 

fig, axes = plt.subplots(3,3, sharex=False, sharey=True)
print("\nWhich of these performance indicators/metrics are important for your organisation/network?\n\n")

for col in df3[:-1].index:
    bars = df3.loc[col].plot.barh(width=.9, figsize=(15, 10), color=color, title=df3.loc[col].name,
                                  ax=axes[i, j])

    for spine in axes[i, j].spines:
        axes[i, j].spines[spine].set_visible(False)

    for bar, pattern in zip(bars.patches, patterns):        
        bar.set_hatch(pattern)
    fig.tight_layout()

    if j==2: 
        if roundcounter==0:
            roundcounter+=1
            i=1
            j=0
        elif roundcounter==1:
            roundcounter+=1
            j=0
            i=2
        elif roundcounter==2:
            i=2
            j=0

    elif j==1 or j==0:
            j+=1

axes[2, 1].axis('off')
axes[2, 2].axis('off')

bars.legend()
plt.savefig('figures/metrics.png')
plt.show() 

作为一个新用户,我还不能发布图片,但可以在这里找到:https://drive.google.com/open?id=1c46FOZnA9aBtDb62kJg8h5bxePoTThrI

【问题讨论】:

  • 在这种情况下,我可能会结合最后两个 Axes 并在那里绘制图例。
  • 我刚刚编辑了这个问题。您能否详细说明如何处理?
  • 请提供可以直接复制粘贴的示例数据,并从您的代码中删除与您的问题不直接相关的所有内容(minimal reproducible example)。
  • 我已按照建议编辑了问题。非常感谢您的帮助。

标签: pandas matplotlib plot series


【解决方案1】:

在尝试了多种解决方案后,我能够解决问题。请参阅下面的代码。原始问题中的库有一个额外的“import matplotlib as mpl”。

#Adding 'Total' row and column to use for sorting.
df3.loc['Total',:]= df3.sum(axis=0)
df3=df3[df3.iloc[-1,:].sort_values(ascending=False).index]
df3['Total'] = df3.sum(axis=1)
df3 = df3.sort_values(by='Total', ascending=False)

i = j = roundcounter = 0
patterns = ['\\', '|', '/', '+', 'x', 'o', 'O', '.', '*', '-']
color=['orange', 'darkseagreen', 'maroon', 'mediumpurple', 'saddlebrown', 'orchid', 'indianred',
      'tomato', 'dimgrey', 'aquamarine'] 

fig, axes = plt.subplots(3,3, sharex=False, sharey=True)
print("\nWhich of these performance indicators/metrics are important for your organisation/network?\n\n")

#Plot the graphs
for col in df3[1:].index:
    bars = df3.loc[col].drop(['Total']).plot.barh(width=.9, figsize=(22, 18), color=color, ax=axes[i, j])

    axes[i, j].set_title(df3.loc[col].name, fontdict={'fontsize': 25, 'fontweight': 'medium'})
    axes[i, j].get_yaxis().set_ticklabels([])

    for tick in axes[i, j].xaxis.get_major_ticks():
            tick.label.set_fontsize(25)

    for spine in axes[i, j].spines:
        axes[i, j].spines[spine].set_visible(False)

    for bar, pattern in zip(bars.patches, patterns):        
        bar.set_hatch(pattern)

    if j==2: 
        if roundcounter==0:
            roundcounter+=1
            i=1
            j=0
        elif roundcounter==1:
            roundcounter+=1
            j=0
            i=2
        elif roundcounter==2:
            i=2
            j=0
    elif j==1 or j==0:
            j+=1

axes[0, 2].set_xticks([0, 4, 8, 12, 16, 20], minor=False)
axes[2, 1].axis('off')
axes[2, 2].axis('off')

labels = df3.loc['Academic Institution'].drop(['Total']).index.tolist()
handles = [rect for rect in bars.get_children() if isinstance(rect, mpl.patches.Rectangle)]
legend = fig.legend(handles, labels, loc=4, fontsize=25)
legend.set_title('Metric/Options Selected',prop={'size':26})

plt.savefig('figures/metrics.png', bbox_inches="tight")
fig.tight_layout()
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2023-03-30
    • 2019-03-20
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多