Putar teks sumbu dalam python matplotlib


314

Saya tidak tahu bagaimana cara memutar teks pada X Axis. Stempel waktu, sehingga ketika jumlah sampel meningkat, mereka semakin dekat dan lebih dekat sampai tumpang tindih. Saya ingin memutar teks 90 derajat sehingga sampel semakin berdekatan, mereka tidak tumpang tindih.

Di bawah ini adalah apa yang saya miliki, ini berfungsi dengan baik dengan pengecualian bahwa saya tidak tahu cara memutar teks sumbu X.

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
Lihat jawaban ini untuk hal-hal penting tentang menyelaraskan label yang diputar dengan ha(horizontal align)
LondonRob

Jawaban:


513

Ini bekerja untuk saya:

plt.xticks(rotation=90)

8
Jika ada orang lain yang menggunakan mpld3, dan merasa frustrasi karena tidak ada solusi yang berfungsi. Rotasi tidak didukung di mpld3.
beetree

4
Poin ekstra untuk membuat ini tetap di dalam gambar / jendela. Punyaku setengah di luar.
Gauthier

1
Sebut ini setelah merencanakan. Yaitu, pertama ax.plot(...)kemudianplt.xticks(rotation=90)
CGFoX

161

Jalan mudah

Seperti dijelaskan di sini , ada metode yang ada di matplotlib.pyplot figurekelas yang secara otomatis merotasikan tanggal dengan tepat untuk Anda.

Anda dapat memanggilnya setelah Anda memplot data Anda (yaitu ax.plot(dates,ydata):

fig.autofmt_xdate()

Jika Anda perlu memformat label lebih lanjut, periksa tautan di atas.

Objek non-datetime

Sesuai komentar languitar , metode yang saya sarankan untuk non-datetime xtickstidak akan diperbarui dengan benar ketika zoom, dll. Jika itu bukan datetimeobjek yang digunakan sebagai data x-axis Anda, Anda harus mengikuti jawaban Tommy :

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

3
Ini cara terbaik karena ringkas, beroperasi pada kutu yang ada secara otomatis, dan menyesuaikan margin plot sehingga dapat dibaca. Metode lain membiarkan kutu keluar dari halaman, membutuhkan tindakan lebih lanjut (seperti plt.tight_layouts ()) untuk menyesuaikannya.
EL_DON

Jika Anda telah menggunakan locator dan formatter, metode "lain" mungkin menghentikan efeknya jika diterapkan sesudahnya.
languitar

73

Banyak jawaban "benar" di sini tetapi saya akan menambahkan satu lagi karena saya pikir beberapa perincian tidak disertakan. OP meminta rotasi 90 derajat tetapi saya akan berubah menjadi 45 derajat karena ketika Anda menggunakan sudut yang tidak nol atau 90, Anda juga harus mengubah perataan horizontal; jika tidak, label Anda akan tidak di tengah dan agak menyesatkan (dan saya rasa banyak orang yang datang ke sini ingin memutar sumbu ke sesuatu selain 90).

Kode termudah / paling tidak

Pilihan 1

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

Seperti disebutkan sebelumnya, itu mungkin tidak diinginkan jika Anda lebih suka mengambil pendekatan Berorientasi Objek.

pilihan 2

Cara cepat lain (ini ditujukan untuk objek tanggal tetapi tampaknya bekerja pada label apa pun; ragu bahwa ini direkomendasikan):

fig.autofmt_xdate(rotation=45)

fig Anda biasanya akan mendapatkan dari:

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

Berorientasi Objek / Berurusan langsung dengan ax

Opsi 3a

Jika Anda memiliki daftar label:

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

Opsi 3b

Jika Anda ingin mendapatkan daftar label dari plot saat ini:

# 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')

Opsi 4

Mirip dengan di atas, tetapi sebaliknya melalui manual.

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

Opsi 5

Kami masih menggunakan pyplot(seperti plt) di sini tetapi berorientasi objek karena kami mengubah properti dari axobjek tertentu .

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

Opsi 6

Opsi ini sederhana, tetapi AFAIK Anda tidak dapat mengatur label dengan menyelaraskan cara ini sehingga opsi lain mungkin lebih baik jika sudut Anda tidak 90.

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

Sunting: Ada diskusi tentang "bug" ini dan perbaikannya berpotensi dijadwalkan untuk v3.2.0: https://github.com/matplotlib/matplotlib/issues/13774


65

Coba pyplot.setp. Saya pikir Anda bisa melakukan sesuatu seperti ini:

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

Saya pikir saya melewatkan langkah sebelumnya. Apakah contoh yang diedit membantu? Saya jauh dari ahli matplotlib, mungkin ada cara yang lebih baik.
opiethehokie

1
Ini sepertinya tidak berfungsi sama sekali- Gambar (pada mesin saya) menjadi benar-benar kacau. garis hitam di seluruh gambar output ... Hampir terlihat seperti kode batang. ini sangat aneh.
tMC

Versi matplotlib manakah ini? Dengan 1.2.0, setp(subplot(111).get_xticklabels(), rotation=90)berfungsi dengan baik dengan backend Qt4Agg. Dalam kasus saya, akan direset oleh plt.hist(), jadi saya memanggilnya setelah, meskipun plt.plot()tidak mengatur ulang, jadi Anda harus baik-baik saja
drevicko

1
@ tMC Dengan mpl 1.2.0, saya menyalin kode Anda (dengan beberapa data dummy), ditambahkan locs, labels = plt.xticks() plt.setp(labels, rotation=90)sebelum plt.plot(time, delay)dan itu bekerja dengan baik.
drevicko

54

Terpisah dari

plt.xticks(rotation=90)

ini juga mungkin:

plt.xticks(rotation='vertical')

Ini bekerja, tetapi ketinggian plot memiliki beberapa masalah
Roberto Marzocchi

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

49

Saya datang dengan contoh serupa. Sekali lagi, kata kunci rotasi adalah .. yah, kuncinya.

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 ) ;

Ini sepertinya berfungsi, tetapi menunjukkan waktu sebagai detik sejak zaman - bukan timestamp daridatetime
tMC

32

Jawaban saya diilhami oleh jawaban cjohnson318, tetapi saya tidak ingin memberikan daftar label yang sudah di-kode; Saya ingin memutar label yang ada:

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

2
Ini sepertinya tidak berfungsi lagi. Tidak ada efek apa pun.
zbyszek

31

Jika menggunakan plt:

plt.xticks(rotation=90)

Dalam kasus menggunakan panda atau burung laut untuk plot, dengan asumsi axsebagai sumbu untuk plot:

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

Cara lain untuk melakukan hal di atas:

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

Semua metode itu sudah ditunjukkan dalam jawaban lain. Apa jawaban yang ditambahkan di sini?
ImportanceOfBeingErnest

@ImportanceOfBeingErnest Ini dimaksudkan untuk membantu mereka yang menggunakan panda atau seaborn, dan tidak matplotlib secara langsung, untuk merencanakan.
Manavalan Gajapathy

for tick in ax.get_xticklabels(): tick.set_rotation(45)melakukan trik untukku.
AP

30

Jika Anda ingin menerapkan rotasi pada objek sumbu, cara termudah adalah menggunakan tick_params. Sebagai contoh.

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

Referensi dokumentasi Matplotlib di sini .

Ini berguna ketika Anda memiliki array sumbu yang dikembalikan oleh plt.subplots, dan lebih mudah daripada menggunakan set_xtickskarena dalam hal itu Anda perlu juga mengatur label centang, dan juga lebih nyaman bahwa mereka yang beralih di atas kutu (untuk alasan yang jelas)


1
Selain itu, solusi ini juga berfungsi dalam fungsi plot panda dataframe karena mengembalikan objek sumbu juga. Periksa di sini . Fungsi yang cukup praktis. pd_dataframe.plot().tick_params(axis='x', labelrotation=90).
metinsenturk

Satu-satunya masalah dengan ini adalah bahwa saya tidak tahu bagaimana cara menyelaraskan label secara horizontal dengan benar jika menggunakan sesuatu seperti labelrotation=30.
getup8


3

Itu akan tergantung pada apa yang Anda rencanakan.

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)

Untuk panda dan burung laut yang memberi Anda objek Sumbu:

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)

Jika Anda perlu memutar label Anda mungkin perlu mengubah ukuran font juga, Anda dapat menggunakannya font_scale=1.0untuk melakukannya.


2

Untuk memutar label sumbu x ke 90 derajat

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

Saya suka sesingkat apa jawaban Anda, tetapi apa yang Anda posting bukan kode Python yang valid. Tidak jelas bagi saya bagaimana menafsirkannya sebagai kode python yang valid.
Dave C

1

Solusi paling sederhana adalah dengan menggunakan:

plt.xticks(rotation=XX)

tetapi juga

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

misalnya untuk tanggal saya menggunakan rotasi = 45 dan bawah = 0,20 tetapi Anda dapat melakukan beberapa tes untuk data Anda

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.