Ich habe frühere Lösungen gelesen, konnte sie aber nicht funktionieren lassen. Ich möchte eine globale Legende für einzelne Subplots haben. Die ax-Objekte von subplot sind durch eine vordefinierte Funktion „get_plot“ aus einer vordefinierten Klasse „The_predefined_plotting_class“ grob wie folgt generiert:Globale Legende für Subplots mit unterschiedlichem Inhalt
Die Funktion gibt ein ax Objekt und jede Objekte ax haben mehr "plots"/aus mehreren Spalten der ursprünglichen "Datendateien".
In einer der Lösungen i auf dieser Seite finden, las ich, dass ich verwenden könnte:
zu einer globalen Legende zu machen. Leider habe ich keine Ahnung, wie man die einzelnen Ax-Objekte (oder die darin enthaltenen Daten) an Handles anhängt, damit dies funktioniert. Jede Zeichnung enthält einige identische Spaltennamen und einige, die sich unterscheiden. Wenn ein Eintrag/Name in vielen Unterplots vorhanden ist, sollte er nur einmal gedruckt werden.
EDIT
Ich bin wirklich leid, dass ich Bilder verwenden musste, aber was auch immer ich die Webside tat habe ich meinen Code nicht zulassen veröffentlichen selbst wenn es im Vorschaufenster richtig angezeigt wurde (die Screenshots stammen aus diesem Fenster)
EDIT2
Wenn ich tue es wie folgt aus:
lines=[]
labels=[]
for idata, datafile in enumerate(datafiles):
MYData = The_predefined_plotting_class.from_file(datafile)
axis[idata] = The_predefined_plotting_class.get_plot(*kwargs)
h, l = axis[idata].get_legend_handles_labels()
lines.append(h)
labels.append(l)
LINES=[]
LABELS=[]
for i in range(0, nrows):
LINES+=lines[i]
LABELS+=labels[i]
plt.legend(LINES, LABELS, loc="upper left", bbox_to_anchor=[0, 1],ncol=3, shadow=True, title="Legend", fancybox=True)
plt.show()
Dann zeigt sie alle Daten. Einige der Daten haben den gleichen Zeilen- und Label-Handler. Ich habe jetzt das Problem, beide Listen zu durchlaufen und nur einen Eintrag zu löschen, wenn in beiden Listen das Tupel(LINES [j]; LABELS [j]) = (LINES [i]; Etiketten [i]) existieren zweimal (und nur dann). Vorzugsweise ist der erste Eintrag:
EDIT3
labels =[]
lines = []
h=["Cat","Mouse","Dog","Cat","Cat","Kangaroo","Dog"]
l=["black","white","brown","white","black","yellow","brown"]
for handle, label in zip(h, l):
if label not in labels :
lines.append(handle)
labels.append(label)
print "The disired Output is :"
print '["Cat","Mouse","Dog","Cat","Kangaroo"]'
print '["black","white","brown","white","yellow"]'
print "currently you get:"
print lines
print labels
Edit4
Ich füge ein "Minimum" Arbeitsbeispiel, das alle möglichen Situationen enthalten soll, die in meinen realen Daten auftreten.
lines=[]
labels=[]
legend_properties = {'weight':'bold','size':10}
# Example data
x1 = np.linspace(0.0, 5.0)
x2 = np.linspace(0.0, 2.0)
a = np.cos(2 * np.pi * x1) * np.exp(-x1)
b = np.cos(2 * np.pi * x2)
c = np.cos(5 * np.pi * x1) * np.exp(-x1)
c2 = np.cos(5 * np.pi * x1**2) * np.exp(-x1)
d = np.cos(2 * np.pi * x2)
d2 = np.cos(2 * np.pi * x2-1)
e = x1*5
e2 = -x1*5
f = np.exp(x1)-e
f2 = (np.exp(x1)-e)/2
nrows = 4
# Plot
fig, axis = plt.subplots(nrows, sharex=True, sharey=False, figsize=(5, 8))
fig.subplots_adjust(hspace=0.0001)
fig.suptitle("Stacked Plots with global Legend wich contains to little elements",fontsize=14,weight='bold')
axis[0].plot(x1, e, 'k--', label='Label1',color="green")
axis[0].plot(x1, e2, 'k--', label='Label2',color="blue")
axis[0].plot(x1, a, 'k--', label='Label3',color="yellow")
axis[1].plot(x1, c, 'k--', label='Label1',color="green")
axis[1].plot(x1, c2, 'k--', label='Label2',color="blue")
axis[1].plot(x1, a, 'k--', label='Label3',color="grey")
axis[2].plot(x2, d, '*', label='Label1',color="green")
axis[2].plot(x2, d2, 'D', label='Label2',color="green")
axis[3].plot(x1, f, 'H', label='Label1',color="green")
axis[3].plot(x1, f2, 'D', label='Label2',color="green")
for i in range(nrows):
h, l = axis[i].get_legend_handles_labels()
for handle, label in zip(h, l):
if label not in labels:
lines.append(handle)
labels.append(label)
# only 3 Legend entrys Label1 , Label2 and Label3 are visible .. Differences in cloors and markers are ignored
plt.legend(handles=lines, labels=labels,bbox_to_anchor=(0., nrows+.02, 1., .102), loc=3,ncol=3, prop=legend_properties,mode="expand", borderaxespad=0.,frameon=False,framealpha=0.0)
plt.show()
EDIT5
dies ist der betreffende Teil des Skripts bilden, wo die tatsächlichen Plots erzeugt werden. "columns" enthält nur die Namen der zu plottenden Daten.
# add plots
ic = 0
for col in columns:
if col == "envelope":
ax.plot(self.data.index, self.data.envelope,
linewidth=LINEWIDTH_envelope, c=last_color, label="")
elif col == "Exp":
ax.plot(self.data.index, self.data.Exp, c=first_color, linestyle="",
label="Exp", marker="o", markersize=MARKERSIZE)
else:
color = used_colors[ic % len(used_colors)]
if fill and "BG" in self.data.columns:
ax.fill_between(self.data.index, self.data.BG,
self.data[col], label=col, alpha=ALPHA,
color=color)
else:
ax.plot(self.data.index, self.data[col], linewidth=LINEWIDTH,
c=color, label=col)
ic += 1
EDIT6
Ich habe versucht, eine Lösung zu finden, basierend auf der Idee, die ich hier vorgestellt:
Leider, was für zwei Listen arbeitet Strings enthält, die für die nicht funktioniert Künstler handels scheint es.
import matplotlib.pyplot as plt
import numpy as np
LI=[]
lines=[]
labels=[]
legend_properties = {'weight':'bold','size':10}
# Example data
x1 = np.linspace(0.0, 5.0)
x2 = np.linspace(0.0, 2.0)
a = np.cos(2 * np.pi * x1) * np.exp(-x1)
b = np.cos(2 * np.pi * x2)
c = np.cos(5 * np.pi * x1) * np.exp(-x1)
c2 = np.cos(5 * np.pi * x1**2) * np.exp(-x1)
d = np.cos(2 * np.pi * x2)
d2 = np.cos(2 * np.pi * x2-1)
e = x1*5
e2 = -x1*5
f = np.exp(x1)-e
f2 = (np.exp(x1)-e)/2
nrows = 4
# Plot
fig, axis = plt.subplots(nrows, sharex=True, sharey=False, figsize=(5, 8))
fig.subplots_adjust(hspace=0.0001)
#fig.suptitle("Stacked Plots with global Legend wich contains to little elements",fontsize=14,weight='bold')
axis[0].plot(x1, e, 'k--', label='Label1',color="green")
axis[0].plot(x1, e2, 'k--', label='Label2',color="blue")
axis[0].plot(x1, a, 'k--', label='Label3',color="yellow")
axis[1].plot(x1, c, 'k--', label='Label1',color="green")
axis[1].plot(x1, c2, 'k--', label='Label2',color="blue")
axis[1].plot(x1, a, 'k--', label='Label3',color="grey")
axis[2].plot(x2, d, '*', label='Label1',color="green")
axis[2].plot(x2, d2, 'D', label='Label2',color="green")
axis[3].plot(x1, f, 'H', label='Label1',color="green")
axis[3].plot(x1, f2, 'D', label='Label2',color="green")
for i in range(nrows):
print i
h, l = axis[i].get_legend_handles_labels()
for hl in zip(h,l):
if hl not in LI:
LI.append(hl)
lines.append(LI[-1][0])
labels.append(LI[-1][1])
print LI
# only 3 Legend entrys Label1 , Label2 and Label3 are visible .. Differences in cloors and markers are ignored
plt.legend(handles=lines, labels=labels,bbox_to_anchor=(0., nrows+.02, 1., .102), loc=3,ncol=3, prop=legend_properties,mode="expand", borderaxespad=0.,frameon=False,framealpha=0.0)
plt.show()
denke ich das Problem, dass für die Speicheradresse in
nur die Zeichenfolge im Vergleichif hl not in LI:
nicht der eigentliche Inhalt von „h“?
Lösung auf der Grundlage der Erklärung von ImportanceOfBeingErnest gab in einem verwandten Beitrag Link7:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.mlab as mlab
import math
import matplotlib.collections
def is_inlist(handle, handles):
for h in handles:
if isinstance(handle, matplotlib.collections.PolyCollection) and isinstance(h, matplotlib.collections.PolyCollection):
if np.all(h.get_facecolor() == handle.get_facecolor()) and \
np.all(h.get_linestyle() == handle.get_linestyle()) and \
np.all(h.get_alpha() == handle.get_alpha()):
return True
if isinstance(handle, matplotlib.lines.Line2D) and isinstance(h, matplotlib.lines.Line2D):
if h.get_color() == handle.get_color() and \
h.get_linestyle() == handle.get_linestyle() and \
h.get_marker() == handle.get_marker():
return True
return False
lines=[]
labels=[]
legend_properties = {'weight':'bold','size':10}
# Example data
mu = 0
mu2 = 5
variance = 1
variance2 = 2
sigma = math.sqrt(variance)
sigma2 = math.sqrt(variance2)
x = np.linspace(mu-3*variance,mu+3*variance, 100)
x2 = np.linspace(mu2-3*variance2,mu2+3*variance2, 100)
nrows = 4
# Plot
fig, axis = plt.subplots(nrows, sharex=True, sharey=False, figsize=(5, 8))
fig.subplots_adjust(hspace=0.0001)
#fig.suptitle("Stacked Plots with global Legend wich contains to little elements",fontsize=14,weight='bold')
axis[0].fill_between(x+6,0,mlab.normpdf(x, mu, sigma), color='green',alpha=0.5,label="PEAK1", interpolate=True)
axis[0].fill_between(x+4,0,mlab.normpdf(x, mu, sigma), color='orange',alpha=0.5,label="PEAK2", interpolate=True)
axis[0].fill_between(x+3,0,mlab.normpdf(x, mu, sigma), color='blue',alpha=0.5,label="PEAK3", interpolate=True)
axis[0].fill_between(x+7,0,mlab.normpdf(x, mu, sigma), color='red',alpha=0.5,label="PEAK4", interpolate=True)
axis[0].plot(x2,2.5*mlab.normpdf(x2, mu2, sigma2),color='black',linestyle="",label="Exp", marker="o", markersize=4)
axis[1].fill_between(x+6,0,mlab.normpdf(x, mu, sigma), color='green',alpha=0.5,label="PEAK1", interpolate=True)
axis[1].fill_between(x+4,0,mlab.normpdf(x, mu, sigma), color='purple',alpha=0.5,label="PEAK2", interpolate=True)
axis[1].fill_between(x+3,0,mlab.normpdf(x, mu, sigma), color='blue',alpha=0.5,label="PEAK3", interpolate=True)
axis[1].fill_between(x+7,0,mlab.normpdf(x, mu, sigma), color='red',alpha=0.5,label="PEAK4", interpolate=True)
axis[1].fill_between(x+6.5,0,mlab.normpdf(x, mu, sigma), color='yellow',alpha=0.5,label="PEAK5", interpolate=True)
axis[1].plot(x2,2.5*mlab.normpdf(x2, mu2, sigma2),color='black',linestyle="",label="Exp", marker="o", markersize=4)
axis[2].fill_between(x+6,0,mlab.normpdf(x, mu, sigma), color='green',alpha=0.5,label="PEAK1", interpolate=True)
axis[2].fill_between(x+4,0,mlab.normpdf(x, mu, sigma), color='orange',alpha=0.5,label="PEAK2", interpolate=True)
axis[2].fill_between(x+3,0,mlab.normpdf(x, mu, sigma), color='#73d216',alpha=0.5,label="PEAK3", interpolate=True)
axis[2].fill_between(x+7,0,mlab.normpdf(x, mu, sigma), color='red',alpha=0.5,label="PEAK4", interpolate=True)
axis[2].plot(x2,2.5*mlab.normpdf(x2, mu2, sigma2),color='black',linestyle="",label="Exp", marker="o", markersize=4)
axis[3].fill_between(x+6,0,mlab.normpdf(x, mu, sigma), color='green',alpha=0.5,label="PEAK1", interpolate=True)
axis[3].fill_between(x+4,0,mlab.normpdf(x, mu, sigma), color='purple',alpha=0.5,label="PEAK2", interpolate=True)
axis[3].fill_between(x+3,0,mlab.normpdf(x, mu, sigma), color='blue',alpha=0.5,label="PEAK3", interpolate=True)
axis[3].fill_between(x+7,0,mlab.normpdf(x, mu, sigma), color='red',alpha=0.5,label="PEAK4", interpolate=True)
axis[3].fill_between(x+6.5,0,mlab.normpdf(x, mu, sigma), color='#73d216',alpha=0.5,label="PEAK5", interpolate=True)
axis[3].fill_between(x+5.5,0,mlab.normpdf(x, mu, sigma), color='violet',alpha=0.5,label="PEAK6", interpolate=True)
axis[3].plot(x2,2.5*mlab.normpdf(x2, mu2, sigma2),color='black',linestyle="",label="Exp", marker="o", markersize=4)
for i in range(nrows):
h, l = axis[i].get_legend_handles_labels()
for hi, li in zip(h,l):
if not is_inlist(hi, lines):
lines.append(hi)
labels.append(li)
# only 3 Legend entrys Label1 , Label2 and Label3 are visible .. Differences in cloors and markers are ignored
plt.legend(handles=lines, labels=labels,bbox_to_anchor=(0., nrows-1+.02, 1., .102), loc=3,ncol=3, prop=legend_properties,mode="expand", borderaxespad=0.,frameon=False,framealpha=0.0)
plt.show()
Hier meine realen Daten besser widerspiegelt, wie ich beide matplotlib.collections.PolyCollection) und matplotlib.lines.Line2D haben Objekte, die verglichen werden müssen.
Keine der Lösungen in den Fragen für Sie linked gearbeitet? Ich würde vorschlagen, eine einfache 'ax.legend (bbox_to_anchor = (1.05, 0), loc = 'lower center', borderaxespad = 0.)' –
Sie müssen den Code manuell eingeben, irgendwie fügen Sie in Screenshots von der Code. – ngoldbaum
Wenn ich das mache, was Sie vorschlagen, bekomme ich: AttributeError: 'numpy.darray' Objekt hat kein Attribut 'legende'! Ich habe oben eine Frage hinzugefügt. – NorrinRadd