2013-05-25 1 views
6

Wir haben einen Code, creates figures from input.txt files. Wir müssen 2 dieser Zahlen in einem einzigen Teilplot kombinieren. Die Daten aus figure1 wird in der linken subplot und von figure2 im rechten subplot aufgetragen werden, um die gleiche Legende teilen und Entsprechung der gleichen Maßstab in den Achsen x und y:matplotlib: Kombiniere verschiedene Figuren und lege sie in einem einzigen Teilplot zusammen, der eine gemeinsame Legende teilt

enter image description here

Hier gibt es einige Beispieldaten:

x = [ 1, 2, 3, 5, 10, 100, 1000 ] 
y1 = [ 1, 0.822, 0.763, 0.715, 0.680, 0.648, 0.645 ] 
y2 = [ 1, 0.859, 0.812, 0.774, 0.746, 0.721, 0.718 ] 

import matplotlib.pyplot as plt 
# mode 01 from one case 
fig1 = plt.figure() 
ax1 = fig1.add_subplot(111) 
ax1.plot(x, y1, label='mode 01') 
# mode 01 from other case 
fig2 = plt.figure() 
ax2 = fig2.add_subplot(111) 
ax2.plot(x, y2, label='mode 01') 

EDIT: die Methode vorgeschlagen durch @nordev arbeitet. Nun wäre es sehr praktisch, die Objekte ax1 und ax2 an die neue Figur zu übergeben, da sie viel mehr Informationen enthalten. It seems that there is no straightforward way to achieve that.

Die real case has been made available here. Damit es funktioniert, führen Sie bitte plot_both.py.


EDIT2: Es war einfacher, die Routine zu ändern, die die input.txt-Dateien liest. Now it supports multiple plots. Aber die Frage ist immer noch gültig, weil es großartig wäre, das AxesSubplot als ein leicht austauschbares Objekt unter verschiedenen Figuren, Teilplots und so weiter zu behandeln ...

+1

Nur um klar zu sein: Sie sind nicht in der Lage, diese Daten einfach als zwei Unterplots in einer Figur zu plotten, mit der Option 'sharey'? Sie müssen zwei separate Figuren erstellen und danach die Plots extrahieren und zu einer neuen Figur kombinieren? – hooy

+0

Ich versuchte die Sharey-Option, aber es scheint nur die [Achsengrenzen und -ansichten] (http://matplotlib.org/users/recipes.html) zu teilen, nicht die Daten selbst ... und der aktuelle Code erstellen diese einzelnen Zahlen, ich möchte versuchen, sie zu kombinieren, bevor Sie diesen Code ändern ... –

+0

Ich verstehe immer noch nicht ganz, was Sie erreichen möchten. Von der Beispieldarstellung, die Sie einschlossen (Bild Nr. 1), wird die Y-Achse geteilt, und die Daten in jeder Auftragung werden nur in einem Teilplot aufgetragen, d. H. Die Auftragungen sind unabhängig. Von Ihrem Kommentar oben scheint es, dass Sie möchten, dass _both_ Linien in _both_ Nebengeschichten geplottet werden? Wenn Sie möchten, dass z. B. die Zeile 1 nur im Teilplannummer 1 und die Zeile 2 nur im Teilplot Nr. 2 gezeichnet wird, wo die y-Achse die gleichen Grenzen hat (gemeinsame y-Achse), ist dies ziemlich einfach. Kann man nicht einfach die "plot" -Methode mit den gleichen Argumenten wie in 'ax1.plot (...'? – hooy

Antwort

7

Löst das dein Problem?

x = [ 1, 2, 3, 5, 10, 100, 1000 ] 
y1 = [ 1, 0.822, 0.763, 0.715, 0.680, 0.648, 0.645 ] 
y2 = [ 1, 0.859, 0.812, 0.774, 0.746, 0.721, 0.718 ] 

import matplotlib.pyplot as plt 
from matplotlib.transforms import BlendedGenericTransform 
# mode 01 from one case 
fig1 = plt.figure() 
ax1 = fig1.add_subplot(111) 
line1, = ax1.plot(x, y1, label='mode 01') 
# mode 01 from other case 
fig2 = plt.figure() 
ax2 = fig2.add_subplot(111) 
line2, = ax2.plot(x, y2, label='mode 01') 

# Create new figure and two subplots, sharing both axes 
fig3, (ax3, ax4) = plt.subplots(1,2,sharey=True, sharex=True,figsize=(10,5)) 

# Plot data from fig1 and fig2 
line3, = ax3.plot(line1.get_data()[0], line1.get_data()[1]) 
line4, = ax4.plot(line2.get_data()[0], line2.get_data()[1]) 
# If possible (easy access to plotting data) use 
# ax3.plot(x, y1) 
# ax4.lpot(x, y2) 

ax3.set_ylabel('y-axis') 
ax3.grid(True) 
ax4.grid(True) 

# Add legend 
fig3.legend((line3, line4), 
      ('label 3', 'label 4'), 
      loc = 'upper center', 
      bbox_to_anchor = [0.5, -0.05], 
      bbox_transform = BlendedGenericTransform(fig3.transFigure, ax3.transAxes)) 
# Make space for the legend beneath the subplots 
plt.subplots_adjust(bottom = 0.2) 
# Show only fig3 
fig3.show() 

Dies gibt Ausgang wie unten enter image description here

bearbeiten

Mit Blick auf den Code in Ihre hochgeladenen Zip-Datei gesehen, ich würde sagen, dass die meisten der gewünschten Funktionalität erreicht wird?

Ich sehe, Sie haben die Funktion zum Erstellen der Plots geändert, so dass die Lösung für Ihr Problem radikal anders ist, da Sie nicht mehr versuchen, zwei Unterplots von verschiedenen Figuren zu "verschmelzen". Ihre Lösung ist im Grunde die gleiche wie die, die ich oben vorgestellt habe, in dem Sinne, dass beide beide Axes Instanzen als Unterplots auf der gleichen Figur erstellen (geben das gewünschte Layout), und dann Plotten, anstatt Plotten, dann extrahieren/Bewege die Achsen, da es sich ursprünglich um deine Frage handelte.

Wie ich vermutete, die einfachste und triviale Lösung ist, die einzelnen Axes Nebenhandlungen der gleichen Figur zu machen, anstatt sie zu trennen Figuren gebunden zu haben, wie bewegt man Axes Instanz von einem Figure zum anderen ist nicht leicht zu bewerkstelligen (wenn überhaupt möglich), wie in einem Kommentar angegeben. Das "ursprüngliche" Problem scheint immer noch sehr schwierig zu sein, da es einfach ist, eine Axes Instanz zu der _axstackFigure hinzuzufügen, die es schwierig macht, an das gewünschte Layout anzupassen.

Eine Änderung an der ax.legend(... Ihrer aktuellen Code, um die Legende zu machen horizontal zentriert, mit der Spitze knapp unterhalb der Achsen:

# Add this line 
from matplotlib.transforms import BlendedGenericTransform 

# Edit the function call to use the BlendedGenericTransform 
ax.legend(loc='upper center', 
      ncol=7, 
      labelspacing=-0.7, 
      columnspacing=0.75, 
      fontsize=8, 
      handlelength=2.6, 
      markerscale=0.75, 
      bbox_to_anchor=(0.5, -0.05), 
      bbox_transform=BlendedGenericTransform(fig.transFigure, ax.transAxes)) 

Hier wird das bbox_to_anchor Argument sollte innerhalb der Grenzen passen angepasst werden unsere Figur.

Die BlendedGenericTransform erlaubt die Transformationen der X-Achse und Y-Achse unterschiedlich zu sein, was in vielen Situationen sehr nützlich sein kann.

+0

Vielen Dank! Es funktioniert, jetzt versuche ich, die neue Figur das 'AxesSublot'-Objekt zu übergeben, um alles zu nehmen die Informationen aus fig1 und fig2 werden effizienter ... –

+3

@SaulloCastro Nach [diesem Kommentar] (http://stackoverflow.com/questions/6309472/matplotlib-can-i-create-axessubplot-objects-then-add-them -zu-einer-Figur-Instanz # comment18919455_6309636) von Joe Kington (Decem ber '12), 'Axes'-Instanzen sollen nicht zwischen Figuren aufgeteilt werden, wodurch Ihre Anfrage sehr schwer zu erfüllen ist. – hooy

+1

Ich habe die Frage mit einem Link zum echten Fall aktualisiert, nur für den Fall, dass du damit spielen willst ... –

Verwandte Themen