wake-up-neo.com

Achsenklasse - legt explizit die Größe (Breite/Höhe) der Achsen in bestimmten Einheiten fest

Ich möchte mit matplotlib eine Figur erstellen, in der ich die Größe der Achsen explizit angeben kann, d. H. Ich möchte die Breite und Höhe der Bbox der Achsen festlegen.

Ich habe mich überall umgesehen und finde keine Lösung dafür. Was ich normalerweise finde, ist wie man die Größe der kompletten Figur (einschließlich Ticks und Labels) anpasst, zum Beispiel mit fig, ax = plt.subplots(figsize=(w, h)).

Dies ist für mich sehr wichtig, da ich eine 1: 1-Skalierung der Achsen haben möchte, d. H. 1 Einheit Papier entspricht in Wirklichkeit 1 Einheit. Wenn z. B. xrange 0 bis 10 mit Hauptstrich = 1 ist und x-Achse 10 cm ist, dann ist 1 Hauptstrich = 1 cm. Ich werde diese Figur als pdf speichern, um sie in ein Latex-Dokument zu importieren.

Diese Frage brachte ein ähnliches Thema zur Sprache, aber die Antwort löst mein Problem nicht (mit plt.gca().set_aspect('equal', adjustable='box')-Code)

Aus dieser anderen Frage sehe ich, dass es möglich ist, die Achsengröße zu erhalten, aber nicht, wie man sie explizit ändert.

Irgendwelche Ideen, wie ich die Achsenbox-Größe einstellen kann und nicht nur die Figurengröße. Die Figurengröße sollte sich an die Achsengröße anpassen.

Vielen Dank!

Für diejenigen, die mit pgfplots in Latex vertraut sind, wird es gerne etwas Ähnliches wie die scale only axis-Option geben (siehe hier zum Beispiel).

3
Gabriel

Die Achsengröße wird durch die Figurengröße und die Figurenabstände bestimmt, die mit figure.subplots_adjust() eingestellt werden können. Umgekehrt bedeutet dies, dass Sie die Achsengröße einstellen können, indem Sie die Figurengröße unter Berücksichtigung der Figurenabstände einstellen:

import matplotlib.pyplot as plt

def set_size(w,h, ax=None):
    """ w, h: width, height in inches """
    if not ax: ax=plt.gca()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom
    figw = float(w)/(r-l)
    figh = float(h)/(t-b)
    ax.figure.set_size_inches(figw, figh)

fig, ax=plt.subplots()

ax.plot([1,3,2])

set_size(5,5)

plt.show()

Es scheint, dass Matplotlib neue Helper-Klassen hat, mit denen Sie Achsen mit fester Größe definieren können. Demo-Achsen mit fester Größe

2
Max

Ich habe herausgefunden, dass die Antwort von Bedeutung von BeendenErnests, die die Größe der Figur ändert, um die Achsengröße anzupassen, inkonsistente Ergebnisse mit den speziellen Einstellungen der Matplotlib liefert, die ich zur Erstellung von für die Veröffentlichung bereiten Plots verwende. Bei der endgültigen Figurengröße gab es geringfügige Fehler, und ich konnte mit seiner Herangehensweise keinen Weg finden, das Problem zu lösen. Für die meisten Anwendungsfälle halte ich dies für kein Problem, jedoch fielen die Fehler auf, wenn mehrere PDFs für die Veröffentlichung kombiniert wurden.

Anstatt ein minimales Arbeitsbeispiel zu entwickeln, um das eigentliche Problem zu finden, das ich mit dem Ansatz der Größenänderung von Figuren habe, habe ich stattdessen eine Arbeit gefunden, bei der die feste Achsengröße unter Verwendung der Teilerklasse verwendet wird.

from mpl_toolkits.axes_grid1 import Divider, Size
def fix_axes_size_incm(axew, axeh):
    axew = axew/2.54
    axeh = axeh/2.54

    #lets use the tight layout function to get a good padding size for our axes labels.
    fig = plt.gcf()
    ax = plt.gca()
    fig.tight_layout()
    #obtain the current ratio values for padding and fix size
    oldw, oldh = fig.get_size_inches()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom

    #work out what the new  ratio values for padding are, and the new fig size.
    neww = axew+oldw*(1-r+l)
    newh = axeh+oldh*(1-t+b)
    newr = r*oldw/neww
    newl = l*oldw/neww
    newt = t*oldh/newh
    newb = b*oldh/newh

    #right(top) padding, fixed axes size, left(bottom) pading
    hori = [Size.Scaled(newr), Size.Fixed(axew), Size.Scaled(newl)]
    vert = [Size.Scaled(newt), Size.Fixed(axeh), Size.Scaled(newb)]

    divider = Divider(fig, (0.0, 0.0, 1., 1.), hori, vert, aspect=False)
    # the width and height of the rectangle is ignored.

    ax.set_axes_locator(divider.new_locator(nx=1, ny=1))

    #we need to resize the figure now, as we have may have made our axes bigger than in.
    fig.set_size_inches(neww,newh)

Bemerkenswerte Dinge:

  • Wenn Sie set_axes_locator() auf einer Achseninstanz aufrufen, unterbrechen Sie die tight_layout()-Funktion.
  • Die ursprüngliche Größe der Figur ist irrelevant, und die endgültige Größe der Figur wird durch die von Ihnen gewählte Achsengröße und die Größe der Beschriftungen/Hilfsstrichbeschriftungen/nach außen gerichteten Hilfsstriche bestimmt.
  • Dieser Ansatz funktioniert nicht mit Farbskalenbalken.
  • Dies ist mein allererster Stapelüberlauf.
0
BongaCodeBuddy