2
votes

Utilisation des légendes des ruines Hlines dans Matplotlib

J'ai du mal à ajuster ma légende de tracé après avoir ajouté la ligne axiale / hline au niveau 100 dans le graphique. (capture d'écran ajoutée)

s'il existe un moyen de l'exécuter correctement afin qu'aucune information ne soit perdue dans la légende, et peut-être ajouter un autre hline et l'ajouter à la légende.

en ajoutant le code ici, peut-être que je ne l'écris pas correctement.

fig, ax1 = plt.subplots(figsize = (9,6),sharex=True)

BundleFc_Outcome['Spend'].plot(kind = 'bar',color = 'blue',width = 0.4, ax = ax1,position = 1)
#
# Make the y-axis label, ticks and tick labels match the line color.
ax1.set_ylabel('SPEND', color='b', size = 18)
ax1.set_xlabel('Bundle FC',color='w',size = 18)

ax2 = ax1.twinx()
ax2.set_ylabel('ROAS', color='r',size = 18)
ax1.tick_params(axis='x', colors='w',size = 20)
ax2.tick_params(axis = 'y', colors='w',size = 20)
ax1.tick_params(axis = 'y', colors='w',size = 20)
#ax1.text()
#

ax2.axhline(100)
BundleFc_Outcome['ROAS'].plot(kind = 'bar',color = 'red',width = 0.4, ax = ax2,position = 0.25)
plt.grid()
#ax2.set_ylim(0, 4000)
ax2.set_ylim(0,300)
plt.title('ROAS & SPEND By Bundle FC',color = 'w',size= 20)
plt.legend([ax2,ax1],labels = ['SPEND','ROAS'],loc = 0)

Le code donne moi l'image suivante:

 result of above code

Après avoir implémenté la suggestion dans les commentaires, l'image ressemble à ceci (ne résout pas le problème ):

 résultat après modification de l'emplacement de la légende


9 commentaires

Déplacez votre légende sur le côté à l'aide de l'attribut bbox_to_anchor . plt.legend ([ax2, ax1], labels = ['SPEND', 'ROAS'], loc = 'upper right', bbox_to_anchor = (1.25,0.80))


malheureusement, cela ne garde pas la couleur de la légende "Dépenser" (rectangle bleu) intacte, a ajouté l'écran d'impression i.stack.imgur.com/xWbsf.png


Essayez sans attribut ncol. plt.legend ([ax2, ax1], labels = ['SPEND', 'ROAS'], loc = 'upper right', bbox_to_anchor = (1.25,0.80)) ou déplacez bbox_to_anchor plus loin


Comme nous n'avons pas vos données, nous ne pouvons malheureusement pas exécuter votre code pour vérifier le problème. Pourriez-vous essayer d'ajouter une troisième étiquette, dites «test» à votre appel plt.legend pour voir ce qui se passe?


@NihalSangeeth Le problème n'est pas la position de la légende, c'est que le patch bleu pour 'SPEND' est remplacé par la ligne de l'appel hline .


@ ThomasKühn a essayé et échoué plt.legend ([ax2, ax1], labels = ['SPEND', 'ROAS'], loc = 0) envoie seulement 2 axes donc lui donner une 3e étiquette sans 3e variable semble bizarre.


@Talis Je comprends maintenant le problème. En tant que hack, vous pouvez écraser la légende de ax1 pour qu'elle affiche les deux. Veuillez vérifier ma réponse.


écraser sur ax1? veuillez élaborer


plt.legend crée une légende avec une ligne pour SPEND et red_bar pour ROAS. ax1.legend sur la même position crée une légende uniquement pour ax1 avec blue_bar pour SPEND


3 Réponses :


3
votes

Vous pouvez utiliser l'attribut bbox_to_anchor pour définir manuellement l'emplacement de la légende.

ax1.legend([ax1],labels = ['SPEND'],loc='upper right', bbox_to_anchor=(1.25,0.70))
plt.legend([ax2,ax1],labels = ['SPEND','ROAS'],loc='upper right', bbox_to_anchor=(1.25,0.70))

https://matplotlib.org/users/legend_guide.html#legend-location


1 commentaires

réussi à le résoudre sur mon propre plt.title ('ROAS & SPEND By Region', color = 'w', size = 20) fig.legend ([ax2, ax1], labels = ['SPEND', 'ROAS'] , loc = 0) plt.hlines ([100,20], xmin = 0, xmax = 8, color = ['r', 'b'])



2
votes

Donc finalement compris, c'était plus simple pour une raison quelconque Même réussi à ajouter un autre seuil au niveau 2 pour les dépenses minimales. entrez la description de l'image ici

fig, ax1 = plt.subplots(figsize = (9,6),sharex=True)

BundleFc_Outcome['Spend'].plot(kind = 'bar',color = 'blue',width = 0.4, ax = ax1,position = 1)
#
# Make the y-axis label, ticks and tick labels match the line color.
ax1.set_ylabel('SPEND', color='b', size = 18)
ax1.set_xlabel('Region',color='w',size = 18)

ax2 = ax1.twinx()

ax2.set_ylabel('ROAS', color='r',size = 18)
ax1.tick_params(axis='x', colors='w',size = 20)
ax2.tick_params(axis = 'y', colors='w',size = 20)
ax1.tick_params(axis = 'y', colors='w',size = 20)
#ax1.text()
#
BundleFc_Outcome['ROAS'].plot(kind = 'bar',color = 'red',width = 0.4, ax = ax2,position = 0.25)
plt.grid()
#ax2.set_ylim(0, 4000)
ax2.set_ylim(0,300)
plt.title('ROAS & SPEND By Region',color = 'w',size= 20)
fig.legend([ax2,ax1],labels = ['SPEND','ROAS'],loc = 0)
plt.hlines([100,20],xmin = 0,xmax = 8,color= ['r','b'])


2 commentaires

Meilleure solution. +1


Jetez un œil à ma solution au cas où vous en auriez besoin pour des ajouts plus complexes à votre silhouette. Il offre une approche plus générale (centrée sur matplotlib).



1
votes

Je ne recommande pas d'utiliser les fonctions intégrées des pandas pour faire des tracés plus complexes. Aussi, lorsque vous posez une question, il est courant de fournir un exemple minimal et vérifiable (voir ici ). J'ai pris la liberté de simuler votre problème.

En raison du changement d'axes, nous devons générer notre propre légende. Premièrement les résultats:

 entrez la description de l'image ici

Ce qui peut être réalisé avec:

import matplotlib.pyplot as plt, pandas as pd, numpy as np
# generate dummy data.
X  = np.random.rand(10, 2)
X[:,1] *= 1000
x  = np.arange(X.shape[0]) * 2 # xticks
df = pd.DataFrame(X, columns = 'Spend Roast'.split())
# end dummy data

fig, ax1 = plt.subplots(figsize = (9,6),sharex=True)
ax2 = ax1.twinx()

# tmp axes
axes = [ax1, ax2] # setup axes
colors = plt.cm.tab20(x)
width = .5 # bar width

# generate dummy legend
elements = []
# plot data
for idx, col in enumerate(df.columns):
    tax = axes[idx]
    tax.bar(x + idx * width, df[col], label = col, width = width, color = colors[idx])
    element = tax.Line2D([0], [0], color = colors[idx], label = col) # setup dummy label
    elements.append(element)
# desired hline
tax.axhline(200, color = 'red')
tax.set(xlabel = 'Bundle FC', ylabel = 'ROAST')
axes[0].set_ylabel('SPEND')
tax.legend(handles = elements)

p>


0 commentaires