Drehen Sie den Achsentext in der Python-Matplotlib


313

Ich kann nicht herausfinden, wie der Text auf der X-Achse gedreht werden soll. Es ist ein Zeitstempel, so dass sie mit zunehmender Anzahl von Proben immer näher kommen, bis sie sich überlappen. Ich möchte den Text um 90 Grad drehen, damit sich die Samples nicht überlappen, wenn sie näher zusammenrücken.

Unten ist das, was ich habe. Es funktioniert einwandfrei, mit der Ausnahme, dass ich nicht herausfinden kann, wie der Text der X-Achse gedreht werden soll.

import sys

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import datetime

font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 8}

matplotlib.rc('font', **font)

values = open('stats.csv', 'r').readlines()

time = [datetime.datetime.fromtimestamp(float(i.split(',')[0].strip())) for i in values[1:]]
delay = [float(i.split(',')[1].strip()) for i in values[1:]]

plt.plot(time, delay)
plt.grid(b='on')

plt.savefig('test.png')

3
In dieser Antwort finden Sie wichtige Informationen zum Ausrichten der gedrehten Etiketten mit ha(horizontale Ausrichtung)
LondonRob

Antworten:


511

Das funktioniert bei mir:

plt.xticks(rotation=90)

8
Für den Fall, dass jemand anderes mpld3 verwendet und frustriert ist, dass keine dieser Lösungen funktioniert. Die Drehung wird in mpld3 nicht unterstützt.
Beetree

4
Zusätzliche Punkte, damit diese innerhalb der Figur / des Fensters bleiben. Meine sind halb draußen.
Gauthier

1
Nennen Sie dies nach dem Plotten. ax.plot(...)plt.xticks(rotation=90)
Dh

161

Einfacher Weg

Wie hier beschrieben , gibt es in der matplotlib.pyplot figureKlasse eine vorhandene Methode, mit der Datumsangaben automatisch entsprechend Ihrer Figur gedreht werden.

Sie können es aufrufen, nachdem Sie Ihre Daten geplottet haben (dh ax.plot(dates,ydata):

fig.autofmt_xdate()

Wenn Sie die Etiketten weiter formatieren müssen, überprüfen Sie den obigen Link.

Nicht-Datum / Uhrzeit-Objekte

Wie pro languitar ‚s Kommentar, die Methode , die ich für vorgeschlagene nicht-Datetime xticksnicht korrekt aktualisiert , wenn das Zoomen etc. Wenn es nicht ein ist datetimeObjekt verwendet als x-Achsen - Daten, sollten Sie folgen Tommy ‘ s Antwort :

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

3
Dies ist der beste Weg, da es präzise ist, vorhandene automatisch generierte Ticks verarbeitet und die Plotränder so anpasst, dass sie lesbar sind. Bei anderen Methoden werden die Häkchen von der Seite entfernt, und es sind weitere Maßnahmen erforderlich (z. B. plt.tight_layouts ()), um sie anzupassen.
EL_DON

Wenn Sie einen Locator und einen Formatierer verwendet haben, kann die "andere" Methode ihre Wirkung aufheben, wenn sie anschließend angewendet wird.
Languitar

73

Viele "richtige" Antworten hier, aber ich werde noch eine hinzufügen, da ich denke, dass einige Details von mehreren weggelassen wurden. Das OP bat um eine 90-Grad-Drehung, aber ich werde auf 45 Grad wechseln, denn wenn Sie einen Winkel verwenden, der nicht Null oder 90 ist, sollten Sie auch die horizontale Ausrichtung ändern. Andernfalls sind Ihre Beschriftungen außermittig und etwas irreführend (und ich vermute, dass viele Leute, die hierher kommen, die Achsen auf etwas anderes als 90 drehen möchten).

Einfachster / am wenigsten Code

Option 1

plt.xticks(rotation=45, ha='right')

Wie bereits erwähnt, ist dies möglicherweise nicht wünschenswert, wenn Sie lieber den objektorientierten Ansatz wählen.

Option 2

Ein weiterer schneller Weg (er ist für Datumsobjekte vorgesehen, scheint jedoch auf jedem Etikett zu funktionieren; bezweifle jedoch, dass dies empfohlen wird):

fig.autofmt_xdate(rotation=45)

fig Sie würden normalerweise bekommen von:

  • fig = plt.figure()
  • fig, ax = plt.subplots()
  • fig = ax.figure

Objektorientiert / Direkt mit ax

Option 3a

Wenn Sie die Liste der Etiketten haben:

labels = ['One', 'Two', 'Three']
ax.set_xticklabels(labels, rotation=45, ha='right')

Option 3b

Wenn Sie die Liste der Beschriftungen aus dem aktuellen Plot abrufen möchten:

# Unfortunately you need to draw your figure first to assign the labels,
# otherwise get_xticklabels() will return empty strings.
plt.draw()
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')

Option 4

Ähnlich wie oben, jedoch manuell durchlaufen.

for label in ax.get_xticklabels():
  label.set_rotation(45)
  label.set_ha('right')

Option 5

Wir verwenden hier immer noch pyplot(as plt), aber es ist objektorientiert, weil wir die Eigenschaft eines bestimmten axObjekts ändern .

plt.setp(ax.get_xticklabels(), rotation=45, ha='right')

Option 6

Diese Option ist einfach, aber AFAIK Sie können die Beschriftung nicht horizontal ausrichten, sodass eine andere Option möglicherweise besser ist, wenn Ihr Winkel nicht 90 beträgt.

ax.tick_params(axis='x', labelrotation=45)

Bearbeiten: Es gibt eine Diskussion über diesen genauen "Fehler" und ein Fix ist möglicherweise geplant für v3.2.0: https://github.com/matplotlib/matplotlib/issues/13774


65

Versuchen Sie es mit pyplot.setp. Ich denke, Sie könnten so etwas tun:

x = range(len(time))
plt.xticks(x,  time)
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)
plt.plot(x, delay)

2
Traceback (most recent call last): File "plotter.py", line 23, in <module> plt.setp(time, rotation=90) File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 183, in setp ret = _setp(*args, **kwargs) File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 1199, in setp func = getattr(o, funcName) AttributeError: 'datetime.datetime' object has no attribute 'set_rotation'
tMC

Ich glaube, ich habe einen Schritt früher verpasst. Hilft das bearbeitete Beispiel? Ich bin weit entfernt von einem Matplotlib-Experten, es könnte einen besseren Weg geben.
Opiethehokie

1
Dies scheint überhaupt nicht zu funktionieren. Das Image (auf meinem Computer) ist völlig durcheinander. schwarze Linien im gesamten Ausgabebild ... Sieht fast wie ein Barcode aus. Es ist sehr seltsam.
tMC

Welche Version von Matplotlib war das? Funktioniert mit 1.2.0 setp(subplot(111).get_xticklabels(), rotation=90)problemlos mit dem Qt4Agg-Backend. In meinem Fall wird es von zurückgesetzt plt.hist(), also rufe ich es nachher auf, setze es plt.plot()aber nicht zurück, also sollten Sie in Ordnung sein.
Drevicko

1
@tMC Mit mpl 1.2.0 habe ich Ihren Code (mit einigen Dummy-Daten) kopiert, locs, labels = plt.xticks() plt.setp(labels, rotation=90)kurz zuvor hinzugefügt plt.plot(time, delay)und es hat gut funktioniert.
Drevicko

54

Appart von

plt.xticks(rotation=90)

das ist auch möglich:

plt.xticks(rotation='vertical')

Es funktioniert, aber die Höhe der Handlung hat ein Problem
Roberto Marzocchi

plt.xticks(rotation=45) plt.savefig(nomefile,dpi=150, optimize=True) plt.clf()
Roberto Marzocchi

49

Ich habe mir ein ähnliches Beispiel ausgedacht. Wieder ist das Rotationsschlüsselwort ... nun, es ist der Schlüssel.

from pylab import *
fig = figure()
ax = fig.add_subplot(111)
ax.bar( [0,1,2], [1,3,5] )
ax.set_xticks( [ 0.5, 1.5, 2.5 ] )
ax.set_xticklabels( ['tom','dick','harry'], rotation=45 ) ;

Das sieht so aus, als würde es funktionieren, aber es zeigt die Zeit als Sekunden seit der datetime
Epoche

32

Meine Antwort ist von der Antwort von cjohnson318 inspiriert, aber ich wollte keine fest codierte Liste von Etiketten liefern. Ich wollte die vorhandenen Beschriftungen drehen:

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

2
Das scheint nicht mehr zu funktionieren. Es gibt überhaupt keine Wirkung.
Zbyszek

31

Bei Verwendung von plt:

plt.xticks(rotation=90)

Wenn Sie Pandas oder Seaborn zum Plotten verwenden, nehmen Sie axals Achsen für das Plotten an :

ax.set_xticklabels(ax.get_xticklabels(), rotation=90)

Eine andere Möglichkeit, Folgendes zu tun:

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

Alle diese Methoden wurden bereits in anderen Antworten gezeigt. Was fügt diese Antwort hier hinzu?
ImportanceOfBeingErnest

@ImportanceOfBeingErnest Es soll denjenigen helfen, die Pandas oder Seaborn und nicht direkt Matplotlib zum Plotten verwenden.
Manavalan Gajapathy

for tick in ax.get_xticklabels(): tick.set_rotation(45)hat den Trick für mich gemacht.
AP

30

Wenn Sie das Achsenobjekt drehen möchten, ist die Verwendung am einfachsten tick_params. Beispielsweise.

ax.tick_params(axis='x', labelrotation=90)

Matplotlib-Dokumentationsreferenz hier .

Dies ist nützlich, wenn Sie ein Array von Achsen haben, wie von zurückgegeben plt.subplots, und es ist bequemer als die Verwendung, set_xticksda Sie in diesem Fall auch die Tick-Beschriftungen festlegen müssen und auch bequemer als diejenigen, die über die Ticks iterieren (aus offensichtlichen Gründen).


1
Darüber hinaus funktioniert diese Lösung auch in der Plotfunktion von pandas dataframe, da sie auch Achsenobjekte zurückgibt. Überprüfen Sie hier . Sehr praktische Funktion. pd_dataframe.plot().tick_params(axis='x', labelrotation=90).
Metinsenturk

Das einzige Problem dabei ist, dass ich nicht herausfinden kann, wie die Beschriftungen bei richtiger Verwendung horizontal korrekt ausgerichtet werden labelrotation=30.
Getup8


3

Es wird davon abhängen, was Sie planen.

import matplotlib.pyplot as plt

 x=['long_text_for_a_label_a',
    'long_text_for_a_label_b',
    'long_text_for_a_label_c']
y=[1,2,3]
myplot = plt.plot(x,y)
for item in myplot.axes.get_xticklabels():
    item.set_rotation(90)

Für Pandas und Seaborn, die Ihnen ein Axes-Objekt geben:

df = pd.DataFrame(x,y)
#pandas
myplot = df.plot.bar()
#seaborn 
myplotsns =sns.barplot(y='0',  x=df.index, data=df)
# you can get xticklabels without .axes cause the object are already a 
# isntance of it
for item in myplot.get_xticklabels():
    item.set_rotation(90)

Wenn Sie Beschriftungen drehen müssen, müssen Sie möglicherweise auch die Schriftgröße ändern. Sie können dies verwenden font_scale=1.0.


2

Drehen der Beschriftung der x-Achse um 90 Grad

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

Mir gefällt, wie kurz Ihre Antwort ist, aber was Sie gepostet haben, ist kein gültiger Python-Code. Mir ist nicht klar, wie ich es als gültigen Python-Code interpretieren soll.
Dave C

1

Die einfachste Lösung ist zu verwenden:

plt.xticks(rotation=XX)

aber auch

# Tweak spacing to prevent clipping of tick-labels
plt.subplots_adjust(bottom=X.XX)

zB für Daten habe ich Rotation = 45 und unten = 0,20 verwendet, aber Sie können einige Tests für Ihre Daten durchführen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.