Xoay văn bản trục trong matplotlib python


313

Tôi không thể tìm ra cách xoay văn bản trên Trục X. Đó là một dấu ấn thời gian, vì vậy khi số lượng mẫu tăng lên, chúng càng ngày càng gần hơn cho đến khi chúng trùng nhau. Tôi muốn xoay văn bản 90 độ để các mẫu gần nhau hơn, chúng không bị chồng chéo.

Dưới đây là những gì tôi có, nó hoạt động tốt với ngoại lệ mà tôi không thể tìm ra cách xoay văn bản trục 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
Xem câu trả lời này để biết nội dung quan trọng về việc căn chỉnh các nhãn được xoay với ha(căn chỉnh theo chiều ngang)
LondonRob

Câu trả lời:


512

Điều này làm việc cho tôi:

plt.xticks(rotation=90)

8
Trong trường hợp bất cứ ai khác đang sử dụng mpld3, và thất vọng về không có giải pháp nào trong số này hoạt động. Xoay không được hỗ trợ trong mpld3.
beetree

4
Thêm điểm để làm cho những người ở lại trong hình / cửa sổ. Của tôi là một nửa bên ngoài.
Gauthier

1
Gọi đây sau khi âm mưu. Tức là, đầu tiên ax.plot(...)sau đóplt.xticks(rotation=90)
CGFoX

161

Cách dễ dàng

Như được mô tả ở đây , có một phương thức hiện có trong matplotlib.pyplot figurelớp tự động xoay ngày thích hợp cho bạn hình.

Bạn có thể gọi nó sau khi bạn vẽ dữ liệu của mình (ví dụ ax.plot(dates,ydata):

fig.autofmt_xdate()

Nếu bạn cần định dạng nhãn hơn nữa, hãy kiểm tra liên kết trên.

Các đối tượng không theo thời gian

Theo nhận xét của langphin , phương pháp tôi đề xuất cho phi thời gian xtickssẽ không cập nhật chính xác khi thu phóng, v.v. Nếu đó không phải là một datetimeđối tượng được sử dụng làm dữ liệu trục x của bạn, bạn nên làm theo câu trả lời của Tommy :

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

3
Đây là cách tốt nhất vì nó ngắn gọn, nó hoạt động trên các tick được tạo tự động hiện có và nó điều chỉnh lề của cốt truyện để có thể đọc được. Các phương pháp khác để các dấu tick tắt trang, yêu cầu thêm hành động (chẳng hạn như plt.tight_layouts ()) để điều chỉnh chúng.
EL_DON

Trong trường hợp bạn đã sử dụng công cụ định vị và định dạng, phương thức "khác" có thể phá vỡ hiệu ứng của chúng nếu được áp dụng sau đó.
lang Ức

73

Nhiều câu trả lời "chính xác" ở đây nhưng tôi sẽ thêm một câu nữa vì tôi nghĩ một số chi tiết bị bỏ sót. OP yêu cầu xoay 90 độ nhưng tôi sẽ thay đổi thành 45 độ vì khi bạn sử dụng góc không bằng 0 hoặc 90, bạn cũng nên thay đổi căn chỉnh ngang; nếu không, nhãn của bạn sẽ lệch tâm và hơi sai lệch (và tôi đoán nhiều người đến đây muốn xoay trục sang thứ gì đó ngoài 90).

Mã dễ nhất / ít nhất

lựa chọn 1

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

Như đã đề cập trước đây, điều đó có thể không được mong muốn nếu bạn muốn thực hiện phương pháp Hướng đối tượng.

Lựa chọn 2

Một cách nhanh khác (nó dành cho các đối tượng ngày nhưng dường như hoạt động trên bất kỳ nhãn nào; nghi ngờ điều này được khuyến nghị mặc dù):

fig.autofmt_xdate(rotation=45)

fig bạn thường sẽ nhận được từ:

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

Hướng đối tượng / Xử lý trực tiếp với ax

Lựa chọn 3a

Nếu bạn có danh sách các nhãn:

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

Tùy chọn 3b

Nếu bạn muốn lấy danh sách các nhãn từ lô hiện tại:

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

Lựa chọn 4

Tương tự như trên, nhưng lặp qua thủ công thay thế.

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

Lựa chọn 5

Chúng tôi vẫn sử dụng pyplot(như plt) ở đây nhưng nó hướng đối tượng vì chúng tôi đang thay đổi thuộc tính của một axđối tượng cụ thể .

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

Lựa chọn 6

Tùy chọn này đơn giản, nhưng AFAIK bạn không thể đặt nhãn theo chiều ngang theo cách này để tùy chọn khác có thể tốt hơn nếu góc của bạn không 90.

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

Chỉnh sửa: Có thảo luận về "lỗi" chính xác này và bản sửa lỗi có khả năng được dự kiến ​​cho v3.2.0: https://github.com/matplotlib/matplotlib/issues/13774


65

Hãy thử pyplot.setp. Tôi nghĩ bạn có thể làm một cái gì đó như thế này:

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

Tôi nghĩ rằng tôi đã bỏ lỡ một bước trước đó. Có ví dụ chỉnh sửa giúp? Tôi xa một chuyên gia matplotlib, có thể có một cách tốt hơn.
opiethehokie

1
Điều này dường như hoàn toàn không hoạt động- Hình ảnh (trên máy của tôi) hoàn toàn bị rối tung. các đường màu đen trên hình ảnh đầu ra ... Gần giống như mã vạch. nó rất kỳ quặc
tMC

Phiên bản nào của matplotlib là đây? Với 1.2.0, setp(subplot(111).get_xticklabels(), rotation=90)hoạt động tốt với phụ trợ Qt4Agg. Trong trường hợp của tôi, nó được thiết lập lại bởi plt.hist()vì vậy tôi gọi nó sauplt.plot() không thiết lập lại nó, vì vậy bạn sẽ ổn thôi.
drevicko

1
@tMC Với mpl 1.2.0, tôi đã sao chép mã của bạn (với một số dữ liệu giả), được thêm vào locs, labels = plt.xticks() plt.setp(labels, rotation=90)trước đó plt.plot(time, delay)và nó hoạt động tốt.
drevicko

54

Giao dịch từ

plt.xticks(rotation=90)

điều này cũng có thể:

plt.xticks(rotation='vertical')

Nó hoạt động, nhưng chiều cao của cốt truyện có một số vấn đề
Roberto Marzocchi

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

49

Tôi đã đưa ra một ví dụ tương tự. Một lần nữa, từ khóa xoay là .. tốt, đó là chìa khóa.

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

Điều này có vẻ như nó hoạt động, nhưng nó hiển thị thời gian là vài giây kể từ thời điểm đó - không phải là dấu thời gian từdatetime
tMC

32

Câu trả lời của tôi được lấy cảm hứng từ câu trả lời của cjohnson318, nhưng tôi không muốn cung cấp một danh sách nhãn cứng; Tôi muốn xoay các nhãn hiện có:

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

2
Điều này dường như không còn hoạt động nữa. Không có tác dụng gì.
zbyszek

31

Nếu sử dụng plt:

plt.xticks(rotation=90)

Trong trường hợp sử dụng gấu trúc hoặc cá ngựa để vẽ, giả sử axlà trục cho âm mưu:

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

Một cách khác để làm như trên:

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

Tất cả những phương pháp đã được hiển thị trong các câu trả lời khác. Câu trả lời này thêm vào đây là gì?
ImportanceOfByingErnest

@ImportanceOfByingErnest Nó có nghĩa là giúp những người sử dụng gấu trúc hoặc cá ngựa, chứ không phải matplotlib trực tiếp, cho âm mưu.
Manavalan Gajapathy

for tick in ax.get_xticklabels(): tick.set_rotation(45)đã lừa tôi
AP

30

Nếu bạn muốn áp dụng xoay trên đối tượng trục, cách dễ nhất là sử dụng tick_params. Ví dụ.

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

Tài liệu tham khảo Matplotlib tại đây .

Điều này hữu ích khi bạn có một loạt các trục được trả về plt.subplotsvà thuận tiện hơn so với sử dụng set_xticksvì trong trường hợp đó, bạn cũng cần đặt nhãn tick và cũng thuận tiện hơn khi những cái đó lặp đi lặp lại trên tick (vì lý do rõ ràng)


1
Ngoài ra, giải pháp này cũng hoạt động trong chức năng cốt truyện của pandas dataframe vì nó cũng trả về đối tượng trục. Kiểm tra tại đây . Chức năng khá tiện dụng. pd_dataframe.plot().tick_params(axis='x', labelrotation=90).
metinsenturk

Vấn đề duy nhất là tôi không thể tìm ra cách sắp xếp các nhãn chính xác theo chiều ngang nếu sử dụng một cái gì đó như labelrotation=30.
getup8


3

Nó sẽ phụ thuộc vào những gì bạn đang âm mưu.

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)

Đối với gấu trúc và cá ngựa cung cấp cho bạn một đối tượng Axes:

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)

Nếu bạn cần xoay nhãn bạn cũng có thể cần thay đổi kích thước phông chữ, bạn có thể sử dụng font_scale=1.0để làm điều đó.


2

Để xoay nhãn trục x đến 90 độ

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

Tôi thích câu trả lời của bạn ngắn như thế nào, nhưng những gì bạn đăng không phải là mã Python hợp lệ. Tôi không rõ làm thế nào để giải thích nó là mã python hợp lệ.
Dave C

1

Giải pháp đơn giản nhất là sử dụng:

plt.xticks(rotation=XX)

nhưng cũng

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

ví dụ: đối với ngày tôi đã sử dụng rotation = 45 và bottom = 0.20 nhưng bạn có thể thực hiện một số kiểm tra cho dữ liệu của mình

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.