2012-06-29 37 views
79

Tôi đang gặp sự cố khi cố gắng để có được các dấu tick ngày của tôi được xoay trong matplotlib. Một chương trình mẫu nhỏ dưới đây. Nếu tôi cố gắng để xoay các ve ở cuối, bọ ve không được xoay. Nếu tôi cố gắng để xoay ve như được hiển thị dưới bình luận 'tai nạn', sau đó matplot lib tai nạn.Đánh dấu ngày và xoay trong matplotlib

Điều này chỉ xảy ra nếu giá trị x là ngày. Nếu tôi thay thế biến số dates bằng biến số t trong cuộc gọi đến avail_plot, cuộc gọi xticks(rotation=70) hoạt động tốt bên trong avail_plot.

Bất kỳ ý tưởng nào?

import numpy as np 
import matplotlib.pyplot as plt 
import datetime as dt 

def avail_plot(ax, x, y, label, lcolor): 
    ax.plot(x,y,'b') 
    ax.set_ylabel(label, rotation='horizontal', color=lcolor) 
    ax.get_yaxis().set_ticks([]) 

    #crashes 
    #plt.xticks(rotation=70) 

    ax2 = ax.twinx() 
    ax2.plot(x, [1 for a in y], 'b') 
    ax2.get_yaxis().set_ticks([]) 
    ax2.set_ylabel('testing') 

f, axs = plt.subplots(2, sharex=True, sharey=True) 
t = np.arange(0.01, 5, 1) 
s1 = np.exp(t) 
start = dt.datetime.now() 
dates=[] 
for val in t: 
    next_val = start + dt.timedelta(0,val) 
    dates.append(next_val) 
    start = next_val 

avail_plot(axs[0], dates, s1, 'testing', 'green') 
avail_plot(axs[1], dates, s1, 'testing2', 'red') 
plt.subplots_adjust(hspace=0, bottom=0.3) 
plt.yticks([0.5,],("","")) 
#doesn't crash, but does not rotate the xticks 
#plt.xticks(rotation=70) 
plt.show() 
+0

Tạo một âm mưu với các ngày trên trục x là một nhiệm vụ chung như vậy - một sự xấu hổ không có đầy đủ hơn ví dụ ngoài kia. – alexw

+0

Tôi tự hỏi nếu đây không phải là bản sao của https://stackoverflow.com/questions/10998621/rotate-axis-text-in-python-matplotlib – ImportanceOfBeingErnest

Trả lời

143

Nếu bạn thích một cách tiếp cận phi hướng đối tượng, di chuyển plt.xticks (xoay = 70) sang phải trước hai cuộc gọi avail_plot, ví dụ:

plt.xticks(rotation=70) 
avail_plot(axs[0], dates, s1, 'testing', 'green') 
avail_plot(axs[1], dates, s1, 'testing2', 'red') 

này thiết lập thuộc tính luân chuyển trước khi thiết lập nhãn. Vì bạn có hai trục ở đây, plt.xticks bị nhầm lẫn sau khi bạn đã tạo hai ô. Tại thời điểm plt.xticks không làm bất cứ điều gì, plt.gca() làm không cung cấp cho bạn các trục bạn muốn sửa đổi và vì vậy plt.xticks, hoạt động trên các trục hiện tại, sẽ không hoạt động.

Đối với một cách tiếp cận hướng đối tượng không sử dụng plt.xticks, bạn có thể sử dụng

plt.setp(axs[1].xaxis.get_majorticklabels(), rotation=70) 

sau hai cuộc gọi avail_plot. Điều này đặt luân phiên trên trục chính xác cụ thể.

+8

Một điều tiện lợi khác: khi bạn gọi 'plt.setp' bạn có thể đặt nhiều tham số bằng cách chỉ định chúng làm đối số từ khóa bổ sung. 'horizontalalignment' kwarg đặc biệt hữu ích khi bạn xoay các nhãn tick:' plt.setp (axs [1] .xaxis.get_majorticklabels(), rotation = 70, horizontalalignment = 'right') ' – 8one6

+2

Tôi không thích giải pháp này vì nó trộn lẫn các phương pháp tiếp cận hướng đối tượng và pyplot. Bạn chỉ có thể gọi 'ax.tick_params (trục = 'x', xoay = 70)' tại bất kỳ nơi nào. –

+1

@TedPetrou Bạn có ý gì khi "trộn" ở đây? giải pháp 'plt.setp' hoàn toàn hướng đối tượng. Nếu bạn không thích thực tế là có một số 'plt' trong đó, hãy sử dụng' từ tập hợp nhập khẩu matplotlib.artist; Thay vào đó, setp (ax.get_xticklabels(), rotation = 90) '. – ImportanceOfBeingErnest

7

Một cách khác để áp dụng horizontalalignmentrotation mỗi nhãn đánh dấu được thực hiện một vòng lặp for trên nhãn đánh dấu bạn muốn thay đổi:

import numpy as np 
import matplotlib.pyplot as plt 
import datetime as dt 

now = dt.datetime.now() 
hours = [now + dt.timedelta(minutes=x) for x in np.arange(0,24*60,10)] 
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)] 
hours_value = np.random.random(len(hours)) 
days_value = np.random.random(len(days)) 

fig, axs = plt.subplots(2) 
fig.subplots_adjust(hspace=0.75) 
axs[0].plot(hours,hours_value) 
axs[1].plot(days,days_value) 

for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels(): 
    label.set_rotation(30) 
    label.set_horizontalalignment("right") 

enter image description here

Và đây là một ví dụ nếu bạn muốn kiểm soát vị trí của ve lớn và nhỏ:

import numpy as np 
import matplotlib.pyplot as plt 
import datetime as dt 

fig, axs = plt.subplots(2) 
fig.subplots_adjust(hspace=0.75) 
now = dt.datetime.now() 
hours = [now + dt.timedelta(minutes=x) for x in np.arange(0,24*60,10)] 
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)] 

axs[0].plot(hours,np.random.random(len(hours))) 
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True) 
x_minor_lct = matplotlib.dates.HourLocator(byhour = range(0,25,1)) 
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct) 
axs[0].xaxis.set_major_locator(x_major_lct) 
axs[0].xaxis.set_minor_locator(x_minor_lct) 
axs[0].xaxis.set_major_formatter(x_fmt) 
axs[0].set_xlabel("minor ticks set to every hour, major ticks start with 00:00") 

axs[1].plot(days,np.random.random(len(days))) 
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True) 
x_minor_lct = matplotlib.dates.DayLocator(bymonthday = range(0,32,1)) 
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct) 
axs[1].xaxis.set_major_locator(x_major_lct) 
axs[1].xaxis.set_minor_locator(x_minor_lct) 
axs[1].xaxis.set_major_formatter(x_fmt) 
axs[1].set_xlabel("minor ticks set to every day, major ticks show first day of month") 
for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels(): 
    label.set_rotation(30) 
    label.set_horizontalalignment("right") 

enter image description here

16

Một giải pháp dễ dàng mà tránh lặp qua ticklabes là chỉ cần sử dụng

fig.autofmt_xdate()

Lệnh này sẽ tự động xoay các nhãn Xaxis và điều chỉnh vị trí của họ. Giá trị mặc định là góc xoay 30 ° và căn chỉnh ngang "phải". Nhưng họ có thể được thay đổi trong lời gọi hàm

fig.autofmt_xdate(bottom=0.2, rotation=30, ha='right') 

Các thêm bottom đối số là tương đương với thiết plt.subplots_adjust(bottom=bottom), cho phép để thiết lập đáy trục đệm đến một giá trị lớn hơn để lưu trữ các ticklabels xoay.

Vì vậy, về cơ bản ở đây bạn có tất cả các cài đặt bạn cần để có trục ngày đẹp trong một lệnh duy nhất.

Có thể tìm thấy good example trên trang matplotlib.

+0

Câu trả lời hay! Cảm ơn! – Abramodj

9

Giải pháp làm việc cho matplotlib 2.1+

Có tồn tại một phương pháp trục tick_params có thể thay đổi tính chất đánh dấu. Nó cũng tồn tại như một phương pháp trục như set_tick_params

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

Hoặc

ax.xaxis.set_tick_params(rotation=45) 

Là một mặt lưu ý, các giải pháp hiện tại trộn lẫn giao diện stateful (sử dụng pyplot) với giao diện hướng đối tượng bằng cách sử dụng lệnh plt.xticks(rotation=70). Vì mã trong câu hỏi sử dụng cách tiếp cận hướng đối tượng, tốt nhất là nên tuân theo cách tiếp cận đó trong suốt. Các giải pháp thực hiện cho một giải pháp rõ ràng tốt với plt.setp(axs[1].xaxis.get_majorticklabels(), rotation=70)

0

plt.imshow() phương pháp

import matplotlib.pyplot as plt 
import pandas as pd 

corr = df.corr() 
plt.imshow (corr, cmap='Blues') 
plt.xticks(range(len(corr.columns)), corr.columns, rotation=35) 
plt.yticks(range(len(corr.columns)), corr.columns) 
plt.colorbar() 
plt.show() 
Các vấn đề liên quan