2017-04-19 2 views
1

Ich bin neu zu Matplotlib und versuchen, Plots von Pandas Datenrahmen über eine Schleife zu erstellen und zu speichern. Jedes Diagramm sollte eine identische x-Achse, aber unterschiedliche Längen und Beschriftungen der y-Achse haben. Ich habe kein Problem damit, die Plots mit unterschiedlichen y-Achsenlängen und Beschriftungen zu erstellen und zu speichern, aber wenn ich die Plots erstelle, skaliert matplotlib die x-Achse neu, je nachdem wie viel Platz für die y-Achsenbeschriftungen auf der linken Seite benötigt wird Zahl.Machen x-Achsen aller Unterplots gleiche Länge auf der Seite

Diese Zahlen sind für einen technischen Bericht. Ich plane, eine auf jeder Seite des Berichts zu platzieren, und ich möchte, dass alle X-Achsen den gleichen Platz auf der Seite einnehmen.

Hier ist eine MSPaint-Version von dem, was ich bekomme und was ich gerne bekommen würde. MSPaint-drawn plot examples of the problem and desired solution

Hoffentlich ist das genug Code, um zu helfen. Ich bin sicher, dass es viele nicht optimale Teile davon gibt.

import pandas as pd 
import matplotlib.pyplot as plt 
import pylab as pl 
from matplotlib import collections as mc 
from matplotlib.lines import Line2D 
import seaborn as sns 

# elements for x-axis 
start = -1600 
end = 2001 
interval = 200 # x-axis tick interval 
xticks = [x for x in range(start, end, interval)] # create x ticks 

# items needed for legend construction 
lw_bins = [0,10,25,50,75,90,100] # bins for line width 
lw_labels = [3,6,9,12,15,18] # line widths 
def make_proxy(zvalue, scalar_mappable, **kwargs): 
    color = 'black' 
    return Line2D([0, 1], [0, 1], color=color, solid_capstyle='butt', **kwargs) 

# generic image ID 
img_path = r'C:\\Users\\user\\chart' 
img_ID = 0 

for line_subset in data: 
    # create line collection for this run through loop 
    lc = mc.LineCollection(line_subset) 

    # create plot and set properties 
    sns.set(style="ticks") 
    sns.set_context("notebook") 
    fig, ax = pl.subplots(figsize=(16, len(line_subset)*0.5)) # I want the height of the figure to change based on number of labels on y-axis 
                   # Figure width should stay the same 
    ax.add_collection(lc) 
    ax.set_xlim(left=start, right=end) 
    ax.set_xticks(xticks) 
    ax.set_ylim(0, len(line_subset)+1) 
    ax.margins(0.05) 
    sns.despine(left=True) 
    ax.xaxis.set_ticks_position('bottom') 
    ax.set_yticks(line_subset['order']) 
    ax.set_yticklabels(line_subset['ylabel']) 
    ax.tick_params(axis='y', length=0) 

    # legend 
    proxies = [make_proxy(item, lc, linewidth=item) for item in lw_labels] 
    ax.legend(proxies, ['0-10%', '10-25%', '25-50%', '50-75%', '75-90%', '90-100%'], bbox_to_anchor=(1.05, 1.0), 
       loc=2, ncol=2, labelspacing=1.25, handlelength=4.0, handletextpad=0.5, markerfirst=False, 
       columnspacing=1.0) 

    # title 
    ax.text(0, len(line_subset)+2, s=str(img_ID), fontsize=20) 

    # save as .png images 
    plt.savefig(r'C:\\Users\\user\\Desktop\\chart' + str(img_ID) + '.png', dpi=300, bbox_inches='tight') 

Antwort

0

zur X-Achse für die Nebenhandlungen (gleiche x-Achsenlänge für jede subplot) erhalten passend, müssen Sie die x-Achse zwischen Nebenhandlungen teilen.

Siehe Beispiel hier https://matplotlib.org/examples/pylab_examples/shared_axis_demo.html

+0

Gibt es eine justieren Möglichkeit, die X-Achse zu speichern, damit ich sie beim nächsten Durchlauf durch die Schleife verwenden kann? Ich will nicht alle Plots auf einer zusammenhängenden Figur haben; Sie müssen als einzelne .png-Dateien gespeichert werden. – jdep

+0

Sie können x Begrenzungen in einer Temp-Variable speichern. Sagen wir mal von nullter Lauf und wenden es für den nächsten Lauf an (erster Lauf). Möglicherweise haben Sie jedoch das Problem, dass Sie beim zweiten Lauf vom ersten Lauf an Grenzwerte anwenden. das magst du nicht wollen. – plasmon360

2

Sofern Sie eine Achse spezifisch definiert Aspektverhältnisses (wie in einem imshow Grundstück oder durch .set_aspect("equal") Aufruf) verwenden, wird der Raum von den Achsen genommen sollte nur von der Zahl Größe zusammen, dass Richtung und die Abstände auf die Figur eingestellt.

Sie fragen daher ziemlich oft nach dem Standardverhalten, und das Einzige, was Sie daran hindert, ist, dass Sie bbox_inches='tight' im savefig Befehl verwenden.

bbox_inches='tight' wird die Zahlengröße ändern! Also benutze es nicht und die Achsen bleiben in der Größe konstant. `

Ihre Figur Größe, definiert wie figsize=(16, len(line_subset)*0.5) scheint sinnvoll zu sein nach dem, was ich von der Frage verstehe. Was bleibt, ist sicherzustellen, dass die Achsen in der Figur die Größe haben, die sie haben sollen. Sie können das tun, indem sie manuell platzieren fig.add_axes

fig.add_axes([left, bottom, width, height]) 

mit dem left, bottom, width, height in Abbildung sind Koordinaten von 0 bis 1 reicht Oder Sie können die Abstände außerhalb des subplot mit subplots_adjust

plt.subplots_adjust(left, bottom, right, top) 
+0

Das ist es, was ich bekomme, wenn ich unkritisch einen Code entkomme, den ich gefunden habe. Wenn ich jedoch "bbox_inches = 'tight" wegnehme, erscheinen meine y-Achsen-Beschriftungen nur dann vollständig, wenn ich 'figsize' auf einen großen x-Wert (> 25 Zoll) einstelle. Kann ich es irgendwie in eine Größe von 8,5x11 Zoll zwingen? – jdep

+0

Ich habe die Antwort aktualisiert. Hilft dir das? – ImportanceOfBeingErnest

Verwandte Themen