Как создать одну легенду для группы гистограмм, сгенерированных из кадра данных - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть кадр данных, как показано в коде, и я сгенерировал столбчатую диаграмму для каждой строки, используя цикл.Я пытаюсь построить одну легенду для всех графиков в правом нижнем углу, но безуспешно.Я попробовал строки кодов, такие как приведенные ниже - и многие другие нашли онлайн - внутри цикла построения и снаружи безуспешно.Пожалуйста, предложите решение, которое могло бы работать.

#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

1 Ответ

0 голосов
/ 22 апреля 2019

Я могу решить проблему после попытки решения ряда проблем.Смотрите код ниже.В исходном вопросе есть дополнительная '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()
...