Ausgabe
Ich habe eine Modellversion meines Datensatzes erstellt, um mein Problem zu veranschaulichen.
Ich habe so eine Grafik:
import pandas as pd
import matplotlib.pyplot as plt
data = {'x': [0, 1, 2, 3],
'y': [3, 2, 1, 0],
'cat1': ['A', 'B', 'A', 'B'],
'cat2': ['f', 'g', 'h', 'i']}
df = pd.DataFrame(data)
colors = {'A':'tab:red',
'B':'tab:blue'}
markers = {'f':"o",
'g':"v",
'h':"s",
'i':"+"}
fig, ax = plt.subplots()
for i in range(df.shape[0]):
ax.scatter(df.loc[i,'x'],
df.loc[i,'y'],
color=colors[df.loc[i,'cat1']],
marker=markers[df.loc[i,'cat2']],
label = df.loc[i, 'cat2'])
ax.legend()
Aber ich suche eine Legende wie diese:
Kann mir jemand Tipps geben wie ich das lösen kann? Außerdem wäre es besser, wenn die Legende im endgültigen Diagramm in einem Feld außerhalb des Diagramms auf der rechten Seite wäre.
Lösung
Um zusätzliche Linien (A, B) hinzuzufügen, die Reihenfolge neu anzuordnen und die Legende außerhalb des Diagramms zu verschieben, sind dies die Schritte, die Sie nach dem Plotten ausführen können.
- Erstellen Sie benutzerdefinierte Legendeneinträge für die neuen Einträge und verwenden Sie vorhandene
Line2D
- Zeichnen Sie die Legende und verwenden
bbox_to_anchor
Sie , um die Legende an die gewünschte Stelle zu verschieben. Sie können die Koordinaten innerhalb von bbox anpassen, wenn Sie die Position verschieben möchten - Passen Sie die Beschriftungen für A, B an, da dies nur Text (keine Markierung) ist, sodass sie horizontal in der Mitte ausgerichtet sind (Sie können anpassen
set_position()
, ob Sie sie weiter nach links / rechts verschieben möchten
Code
import pandas as pd
import matplotlib.pyplot as plt
data = {'x': [0, 1, 2, 3],
'y': [3, 2, 1, 0],
'cat1': ['A', 'B', 'A', 'B'],
'cat2': ['f', 'g', 'h', 'i']}
df = pd.DataFrame(data)
colors = {'A':'tab:red',
'B':'tab:blue'}
markers = {'f':"o",
'h':"s",
'g':"v",
'i':"+"}
fig, ax = plt.subplots()
for i in range(df.shape[0]):
ax.scatter(df.loc[i,'x'], df.loc[i,'y'],
color=colors[df.loc[i,'cat1']],
marker=markers[df.loc[i,'cat2']],
label = df.loc[i, 'cat2']
## Create legend handle entries for each of the items
from matplotlib.lines import Line2D
title = Line2D([0], [0], linestyle="none", marker="")
f = Line2D([0], [0], linestyle="none", marker="o", markersize=10, markeredgecolor='tab:red', markerfacecolor="tab:red")
g = Line2D([0], [0], linestyle="none", marker="v", markersize=10, markeredgecolor='tab:blue', markerfacecolor="tab:blue")
h = Line2D([0], [0], linestyle="none", marker="s", markersize=10, markeredgecolor='tab:red', markerfacecolor="tab:red")
i = Line2D([0], [0], linestyle="none", marker="+", markersize=10, markeredgecolor='tab:blue', markerfacecolor="tab:blue")
## Plot in order you want, bbox to set legend box outside
leg=ax.legend((title, f, h, title, g, i), ('A', 'f', 'h', 'B', 'g','i'), bbox_to_anchor=(1.16, 1.03))
## Adjust position of A and B so that they are in middle
for item, label in zip(leg.legendHandles, leg.texts):
if label._text in ['A', 'B']:
width=item.get_window_extent(fig.canvas.get_renderer()).width
label.set_ha('left')
label.set_position((-width/2,0)) ## Adjust here to move left/right
Parzelle
Beantwortet von – Redox
Antwort geprüft von – Jay B. (FixError Admin)