Ich habe viel zu lange nachgeforscht, wie zwei Unterplots dieselbe y-Achse mit einer einzigen Farbleiste teilen können, die zwischen den beiden in Matplotlib geteilt wird.
Was geschah, war, dass, wenn ich die colorbar()
Funktion in entweder subplot1
oder subplot2
aufrief, das Diagramm automatisch so skaliert wurde, dass die Farbleiste und das Diagramm in den Begrenzungsrahmen 'Unterzeichnung' passten, was dazu führte, dass die beiden nebeneinander angeordneten Diagramme zwei sehr unterschiedlich waren Größen.
Um dies zu umgehen, habe ich versucht, eine dritte Nebenhandlung zu erstellen, die ich dann gehackt habe, um keine Handlung mit nur einer vorhandenen Farbleiste zu rendern. Das einzige Problem ist, dass jetzt die Höhen und Breiten der beiden Diagramme ungleichmäßig sind und ich nicht herausfinden kann, wie es in Ordnung aussehen soll.
Hier ist mein Code:
from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches
from matplotlib.ticker import NullFormatter
# SIS Functions
TE = 1 # Einstein radius
g1 = lambda x,y: (TE/2) * (y**2-x**2)/((x**2+y**2)**(3/2))
g2 = lambda x,y: -1*TE*x*y / ((x**2+y**2)**(3/2))
kappa = lambda x,y: TE / (2*np.sqrt(x**2+y**2))
coords = np.linspace(-2,2,400)
X,Y = np.meshgrid(coords,coords)
g1out = g1(X,Y)
g2out = g2(X,Y)
kappaout = kappa(X,Y)
for i in range(len(coords)):
for j in range(len(coords)):
if np.sqrt(coords[i]**2+coords[j]**2) <= TE:
g1out[i][j]=0
g2out[i][j]=0
fig = plt.figure()
fig.subplots_adjust(wspace=0,hspace=0)
# subplot number 1
ax1 = fig.add_subplot(1,2,1,aspect='equal',xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{1}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
plt.ylabel(r"y ($\theta_{E}$)",rotation='horizontal',fontsize="15")
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.imshow(g1out,extent=(-2,2,-2,2))
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
e1 = patches.Ellipse((0,0),2,2,color='white')
ax1.add_patch(e1)
# subplot number 2
ax2 = fig.add_subplot(1,2,2,sharey=ax1,xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{2}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
ax2.yaxis.set_major_formatter( NullFormatter() )
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
plt.imshow(g2out,extent=(-2,2,-2,2))
e2 = patches.Ellipse((0,0),2,2,color='white')
ax2.add_patch(e2)
# subplot for colorbar
ax3 = fig.add_subplot(1,1,1)
ax3.axis('off')
cbar = plt.colorbar(ax=ax2)
plt.show()
quelle
vmin
undvmax
Argumente kritisch sind , damit der Farbbalken die Farbe in allen Darstellungen genau wiedergibt . Sie steuern den Farbbereich jedes Unterplots. Wenn Sie über echte Daten verfügen, müssen Sie diese möglicherweise durchlaufen, um zuerst die Min- und Max-Werte zu ermitteln.Sie können den Code von Joe Kington mithilfe des
ax
Parametersfigure.colorbar()
mit einer Liste von Achsen vereinfachen . Aus der Dokumentation :quelle
fig.colorbar(im, ax=axes.ravel().tolist())
. Wenn Sie dies weglassenax=axes.ravel().tolist()
, wird die Farbleiste innerhalb eines Unterplots platziert.Diese Lösung erfordert keine manuelle Anpassung der Achsenpositionen oder der Farbleistengröße, funktioniert mit mehrzeiligen und einzeiligen Layouts und funktioniert mit
tight_layout()
. Es wurde anhand eines GaleriebeispielsImageGrid
aus der AxesGrid Toolbox von matplotlib angepasst .quelle
thecb = ax.cax.colorbar(im)
. Dann können Sie tunthecb.set_label_text("foo")
Die Verwendung
make_axes
ist noch einfacher und führt zu einem besseren Ergebnis. Es bietet auch Möglichkeiten, die Positionierung der Farbleiste anzupassen. Beachten Sie auch die Optionsubplots
, x- und y-Achsen gemeinsam zu nutzen.quelle
nrows=1
, wird die Farbleiste wieder größer als die Unterzeichnungen.Als Anfänger, der über diesen Thread gestolpert ist, möchte ich eine Python-für-Dummies-Adaption von Abevieiramotas sehr ordentlicher Antwort hinzufügen (weil ich auf dem Niveau bin, dass ich nach 'Ravel' suchen musste, um herauszufinden, was ihr Code tat):
Viel weniger pythonisch, viel einfacher für Noobs wie mich zu sehen, was hier tatsächlich passiert.
quelle
Wie in anderen Antworten ausgeführt, besteht die Idee normalerweise darin, Achsen zu definieren, in denen sich die Farbleiste befindet. Es gibt verschiedene Möglichkeiten, dies zu tun. Eine, die noch nicht erwähnt wurde, wäre die direkte Angabe der Farbleistenachsen bei der Erstellung von Unterplots mit
plt.subplots()
. Der Vorteil ist, dass die Achsenposition nicht manuell eingestellt werden muss und in allen Fällen mit automatischem Aspekt die Farbleiste genau die gleiche Höhe wie die Unterzeichnungen hat. Selbst in vielen Fällen, in denen Bilder verwendet werden, ist das Ergebnis wie unten gezeigt zufriedenstellend.Bei
plt.subplots()
der Verwendung vongridspec_kw
Argumenten können die Farbbalkenachsen viel kleiner als die anderen Achsen gemacht werden.Beispiel:
Dies funktioniert gut, wenn der Aspekt der Diagramme automatisch skaliert wird oder die Bilder aufgrund ihres Aspekts in Breitenrichtung (wie oben) verkleinert werden. Wenn die Bilder jedoch breiter als hoch sind, sieht das Ergebnis wie folgt aus, was möglicherweise unerwünscht ist.
Eine Lösung zum Festlegen der Farbbalkenhöhe an der Unterplothöhe wäre
mpl_toolkits.axes_grid1.inset_locator.InsetPosition
das Festlegen der Farbbalkenachsen relativ zu den Bildunterplotachsen.quelle
ax = fig.add_subplot()
stattdessen zu implementieren ? Ich frage, weil ich nicht herausfinden kann, wie ich es mit der Grundkarte verwenden soll.GridSpec
an angebenadd_subplot()
.Die Lösung, eine Liste von Achsen von abevieiramota zu verwenden, funktioniert sehr gut, bis Sie nur eine Bildreihe verwenden, wie in den Kommentaren ausgeführt. Die Verwendung eines angemessenen Seitenverhältnisses
figsize
hilft, ist aber noch lange nicht perfekt. Beispielsweise:Die Farbbalkenfunktion liefert den
shrink
Parameter, der ein Skalierungsfaktor für die Größe der Farbbalkenachsen ist. Es erfordert einige manuelle Versuche und Irrtümer. Beispielsweise:quelle
Um die hervorragende Antwort von @ abevieiramota zu ergänzen, können Sie das Äquivalent von tight_layout mit eingeschränktem_layout erhalten. Sie erhalten immer noch große horizontale Lücken, wenn Sie
imshow
anstelle despcolormesh
durch verwendeten Seitenverhältnisses von 1: 1 verwendenimshow
.quelle
Ich bemerkte, dass fast jede veröffentlichte Lösung
ax.imshow(im, ...)
die Farben, die in der Farbleiste für die mehreren Unterfiguren angezeigt wurden, nicht normalisierte. Dieim
Zuordnung stammt aus der letzten Instanz, aber was ist, wenn die Werte der Vielfachenim
unterschiedlich sind? (Ich gehe davon aus, dass diese Zuordnungen genauso behandelt werden wie die Kontursätze und Oberflächensätze.) Ich habe ein Beispiel mit einem 3D-Oberflächendiagramm unten, das zwei Farbbalken für ein 2x2-Unterdiagramm erstellt (ein Farbbalken pro Zeile) ). Obwohl die Frage explizit nach einer anderen Anordnung fragt, hilft das Beispiel meiner Meinung nach, einige Dinge zu klären.plt.subplots(...)
Aufgrund der 3D-Achsen habe ich leider noch keinen Weg gefunden, dies zu tun .Wenn ich nur die Farbbalken besser positionieren könnte ... (Es gibt wahrscheinlich einen viel besseren Weg, dies zu tun, aber zumindest sollte es nicht allzu schwierig sein, dem zu folgen.)
quelle
im
s unterschiedlich sind, sollten sie nicht dieselbe Farbleiste verwenden, damit die ursprüngliche Frage nicht wirklich zutrifftDieses Thema ist gut behandelt, aber ich möchte dennoch einen anderen Ansatz in einer etwas anderen Philosophie vorschlagen .
Die Einrichtung ist etwas komplexer, ermöglicht aber (meiner Meinung nach) etwas mehr Flexibilität. Zum Beispiel kann man mit den jeweiligen Verhältnissen der einzelnen Unterzeichnungen / Farbbalken spielen:
quelle