หมุนข้อความแกนใน python matplotlib


313

ฉันไม่สามารถหาวิธีหมุนข้อความบนแกน X ได้ มันคือการประทับเวลาดังนั้นเมื่อจำนวนตัวอย่างเพิ่มขึ้นพวกเขาก็จะเข้ามาใกล้กันมากขึ้นจนกว่าจะทับซ้อนกัน ฉันต้องการหมุนข้อความ 90 องศาเพื่อให้กลุ่มตัวอย่างเข้าใกล้กันมากขึ้นพวกเขาจะไม่ทับซ้อนกัน

ด้านล่างคือสิ่งที่ฉันมีมันทำงานได้ดียกเว้นว่าฉันไม่สามารถหาวิธีหมุนข้อความแกน 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
ดูคำตอบนี้สำหรับสิ่งที่สำคัญเกี่ยวกับการจัดตำแหน่งฉลากแบบหมุนด้วยha(จัดเรียงแนวนอน)
LondonRob

คำตอบ:


510

สิ่งนี้ใช้ได้กับฉัน:

plt.xticks(rotation=90)

8
ในกรณีที่คนอื่นกำลังใช้งาน mpld3 และไม่พอใจกับวิธีการแก้ปัญหาเหล่านี้ ไม่รองรับการหมุนใน mpld3
beetree

4
คะแนนพิเศษสำหรับการพักเหล่านี้ภายในรูป / หน้าต่าง ของฉันอยู่ข้างนอกครึ่งหนึ่ง
Gauthier

1
เรียกสิ่งนี้หลังจากพล็อต คือครั้งแรกax.plot(...)แล้วplt.xticks(rotation=90)
CGFoX

161

ทางที่ง่าย

ตามที่อธิบายไว้ที่นี่มีวิธีการที่มีอยู่ในmatplotlib.pyplot figureคลาสที่หมุนวันที่อย่างเหมาะสมโดยอัตโนมัติ

คุณสามารถเรียกมันได้หลังจากที่คุณพล็อตข้อมูลของคุณ (เช่นax.plot(dates,ydata):

fig.autofmt_xdate()

หากคุณต้องการจัดรูปแบบป้ายกำกับเพิ่มเติมให้ชำระเงินที่ลิงก์ด้านบน

วัตถุที่ไม่ใช่วันที่และเวลา

ตามความคิดเห็นของlanguitarวิธีที่ฉันแนะนำสำหรับช่วงเวลาที่ไม่ใช่ datetime xticksจะไม่อัพเดทอย่างถูกต้องเมื่อซูม ฯลฯ หากไม่ใช่datetimeวัตถุที่ใช้เป็นข้อมูลแกน x ของคุณคุณควรทำตามคำตอบของTommy :

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

3
นี่เป็นวิธีที่ดีที่สุดเนื่องจากมีความรัดกุมมันทำงานกับเห็บที่สร้างขึ้นโดยอัตโนมัติที่มีอยู่และปรับระยะขอบของพล็อตเพื่อให้สามารถอ่านได้ วิธีอื่น ๆ ทำให้เห็บหลุดออกจากหน้าซึ่งต้องการการดำเนินการเพิ่มเติม (เช่น plt.tight_layouts ()) เพื่อปรับเปลี่ยน
EL_DON

ในกรณีที่คุณใช้ตัวระบุตำแหน่งและตัวจัดรูปแบบเมธอด "อื่น ๆ " อาจทำให้เอฟเฟ็กต์แตกหักหากใช้ภายหลัง
languitar

73

คำตอบ "ถูกต้อง" มากมายที่นี่ แต่ฉันจะเพิ่มอีกเพราะฉันคิดว่ารายละเอียดบางอย่างออกจากหลาย ๆ OP ขอการหมุน 90 องศา แต่ฉันจะเปลี่ยนเป็น 45 องศาเพราะเมื่อคุณใช้มุมที่ไม่เป็นศูนย์หรือ 90 คุณควรเปลี่ยนการจัดแนวแนวนอนด้วย มิฉะนั้นป้ายกำกับของคุณจะอยู่กึ่งกลางและทำให้เข้าใจผิดเล็กน้อย (และฉันเดาว่ามีหลายคนที่มาที่นี่ต้องการหมุนแกนเป็นอย่างอื่นที่ไม่ใช่ 90)

รหัสที่ง่ายที่สุด / น้อยที่สุด

ตัวเลือกที่ 1

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

ดังที่กล่าวไว้ก่อนหน้านี้อาจไม่เป็นที่น่าพอใจหากคุณต้องการใช้วิธีการที่มุ่งเน้นวัตถุ

ตัวเลือก 2

อีกวิธีที่รวดเร็ว (มีไว้สำหรับวัตถุวันที่ แต่ดูเหมือนว่าจะใช้งานได้บนป้ายกำกับใด ๆ ก็ตาม แต่ขอแนะนำให้ใช้ข้อสงสัยนี้):

fig.autofmt_xdate(rotation=45)

fig คุณมักจะได้รับจาก:

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

เชิงวัตถุ / การจัดการโดยตรงกับ ax

ตัวเลือก 3a

หากคุณมีรายการป้ายกำกับ:

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

ตัวเลือก 3b

หากคุณต้องการรับรายการป้ายกำกับจากพล็อตปัจจุบัน:

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

ตัวเลือก 4

คล้ายกับด้านบน แต่วนซ้ำด้วยตนเองแทน

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

ตัวเลือก 5

เรายังคงใช้pyplot(เป็นplt) ที่นี่ แต่มันเป็นวัตถุเชิงเนื่องจากเรากำลังเปลี่ยนคุณสมบัติของaxวัตถุที่เฉพาะเจาะจง

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

ตัวเลือก 6

ตัวเลือกนี้ง่าย แต่ AFAIK คุณไม่สามารถตั้งค่าการจัดตำแหน่งแนวนอนของป้ายกำกับด้วยวิธีนี้ดังนั้นตัวเลือกอื่นอาจดีกว่าหากมุมของคุณไม่ใช่ 90

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

แก้ไข: มีการอภิปรายเกี่ยวกับ "บั๊ก" ที่แน่นอนนี้และอาจมีการแก้ไขสำหรับv3.2.0: https://github.com/matplotlib/matplotlib/issues/13774


65

ลอง pyplot.setp ฉันคิดว่าคุณสามารถทำสิ่งนี้:

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

ฉันคิดว่าฉันพลาดขั้นตอนก่อนหน้านี้ ตัวอย่างที่แก้ไขมีประโยชน์หรือไม่ ฉันยังห่างไกลจากผู้เชี่ยวชาญ matplotlib แต่อาจมีวิธีที่ดีกว่า
opiethehokie

1
ดูเหมือนจะไม่ได้ผลเลย - ภาพ (บนเครื่องของฉัน) จะเลอะอย่างสมบูรณ์ เส้นสีดำทั่วรูปภาพผลลัพธ์ ... เกือบจะดูเหมือนกับบาร์โค้ด มันแปลกมาก
tMC

รุ่นนี้ของ matplotlib คืออะไร? ด้วย 1.2.0 setp(subplot(111).get_xticklabels(), rotation=90)ทำงานได้ดีกับแบ็คเอนด์ Qt4Agg ในกรณีของฉันมันได้รับการรีเซ็ตplt.hist()ดังนั้นฉันจึงโทรหาแม้ว่าplt.plot()จะไม่ได้รีเซ็ตดังนั้นคุณควรจะโอเค
drevicko

1
@tMC ด้วย mpl 1.2.0 ฉันได้คัดลอกรหัสของคุณ (ด้วยข้อมูลจำลอง) เพิ่มเข้ามาlocs, labels = plt.xticks() plt.setp(labels, rotation=90)ก่อนหน้านี้plt.plot(time, delay)และใช้งานได้ดี
drevicko

54

Appart จาก

plt.xticks(rotation=90)

เป็นไปได้เช่นกัน:

plt.xticks(rotation='vertical')

มันใช้งานได้ แต่ความสูงของพล็อตมีปัญหาบางอย่าง
Roberto Marzocchi

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

49

ฉันมาด้วยตัวอย่างที่คล้ายกัน อีกครั้งคำสำคัญการหมุนคือ .. ก็สำคัญ

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

ดูเหมือนว่าจะใช้งานได้ แต่จะแสดงเวลาเป็นวินาทีนับตั้งแต่กาลเวลาไม่ใช่เวลาประทับจากdatetime
tMC

32

คำตอบของฉันได้รับแรงบันดาลใจจากคำตอบของ cjohnson318 แต่ฉันไม่ต้องการให้รายการป้ายกำกับที่เข้ารหัสยาก ฉันต้องการหมุนป้ายกำกับที่มีอยู่:

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

2
ดูเหมือนจะไม่ทำงานอีกต่อไป ไม่มีผลใด ๆ
zbyszek

31

ถ้าใช้plt:

plt.xticks(rotation=90)

ในกรณีที่ใช้แพนด้าหรือท้องทะเลมาพล็อตโดยถือว่าaxเป็นแกนสำหรับพล็อต:

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

อีกวิธีในการทำด้านบน:

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

วิธีการเหล่านั้นทั้งหมดได้รับการแสดงแล้วในคำตอบอื่น ๆ คำตอบนี้เพิ่มที่นี่คืออะไร?
ImportanceOfBeingErnest

@ImportanceOfBeingErnest มันมีไว้เพื่อช่วยเหลือผู้ที่ใช้แพนด้าหรือนกทะเลและไม่ใช่ matplotlib โดยตรงสำหรับการวางแผน
Manavalan Gajapathy

for tick in ax.get_xticklabels(): tick.set_rotation(45)ทำเคล็ดลับสำหรับฉัน
AP

30

tick_paramsหากคุณต้องการที่จะใช้การหมุนบนวัตถุแกนวิธีที่ง่ายที่สุดคือการใช้ ตัวอย่างเช่น.

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

Matplotlib อ้างอิงเอกสารที่นี่

สิ่งนี้มีประโยชน์เมื่อคุณมีอาเรย์ของแกนตามที่ส่งคืนมาplt.subplotsและสะดวกกว่าการใช้set_xticksเพราะในกรณีนั้นคุณต้องตั้งค่าเลเบลเห็บและสะดวกกว่าที่ทำซ้ำเห็บ (ด้วยเหตุผลที่ชัดเจน)


1
นอกจากนั้นการแก้ปัญหานี้ยังทำงานในฟังก์ชั่นการแปลงของ pandas dataframe เนื่องจากมันส่งคืนวัตถุแกนเช่นกัน ตรวจสอบที่นี่ ฟังก์ชั่นที่มีประโยชน์ค่อนข้าง pd_dataframe.plot().tick_params(axis='x', labelrotation=90).
metinsenturk

labelrotation=30ปัญหาเดียวกับนี้คือว่าฉันไม่สามารถคิดออกว่าจะจัดในแนวนอนฉลากอย่างถูกต้องถ้าใช้สิ่งที่ต้องการ
getup8


3

มันจะขึ้นอยู่กับสิ่งที่คุณวางแผน

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)

สำหรับแพนด้าและทะเลที่ให้วัตถุขวานแก่คุณ:

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)

หากคุณต้องการหมุนป้ายกำกับคุณอาจต้องเปลี่ยนขนาดตัวอักษรด้วยคุณสามารถใช้font_scale=1.0เพื่อทำเช่นนั้นได้


2

หากต้องการหมุนฉลากแกน x เป็น 90 องศา

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

ฉันชอบคำตอบของคุณสั้นแค่ไหน แต่สิ่งที่คุณโพสต์นั้นไม่ถูกต้อง Python code มันไม่ชัดเจนสำหรับฉันที่จะตีความว่าเป็นรหัสไพ ธ อนที่ถูกต้อง
Dave C

1

ทางออกที่ง่ายที่สุดคือการใช้:

plt.xticks(rotation=XX)

แต่ยัง

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

เช่นวันที่ฉันใช้การหมุน = 45 และด้านล่าง = 0.20 แต่คุณสามารถทำการทดสอบข้อมูลของคุณได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.