matplotlib의 날짜 눈금 및 회전


175

matplotlib에서 날짜 눈금을 회전시키는 데 문제가 있습니다. 작은 샘플 프로그램은 다음과 같습니다. 마지막에 진드기를 회전하려고하면 진드기가 회전하지 않습니다. 주석 'crashes'에 표시된대로 눈금을 회전하려고하면 matplot lib가 충돌합니다.

이것은 x- 값이 날짜 인 경우에만 발생합니다. 내가 변수로 대체하는 경우 dates변수와 t의 통화에서을 avail_plot의 xticks(rotation=70)호출은 잘 내부를 작동합니다 avail_plot.

어떤 아이디어?

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

3
x 축에 날짜가있는 플롯을 만드는 것은 일반적인 작업입니다. 더 이상 완전한 예제가 없다는 것은 부끄러운 일입니다.
— alexw

답변:


249

당신은 비 객체 지향 접근, 이동, 원하는 경우 plt.xticks(rotation=70)오른쪽을 하기 전에 두 가지 avail_plot예를 들어 통화,

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

레이블을 설정하기 전에 회전 속성을 설정합니다. 여기에 두 개의 축이 있기 때문에 plt.xticks두 개의 플롯을 만든 후에 혼란스러워집니다. plt.xticks아무것도하지 않는 시점 에서 수정하려는 축을 제공 plt.gca()하지 않으므로plt.xticks 현재 축에 작용하는 작동하지 않습니다.

를 사용하지 않는 객체 지향 접근 방식의 plt.xticks경우

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

두 avail_plot통화 후 . 정확한 축의 회전을 구체적으로 설정합니다.


11
또 다른 편리한 방법 : 호출 plt.setp할 때 추가 키워드 인수로 지정하여 여러 매개 변수를 설정할 수 있습니다. horizontalalignment: 당신이 눈금 레이블을 회전 할 때 kwarg 특히 유용합니다plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70, horizontalalignment='right' )
— 8one6

32
pyplot과 객체 지향 접근 방식을 혼합 하여이 솔루션을 좋아하지 않습니다. ax.tick_params(axis='x', rotation=70)어느 곳에서나 전화 할 수 있습니다 .
— Ted Petrou

3
@TedPetrou 여기서 "믹싱"이란 무슨 뜻입니까? plt.setp솔루션은 완전히 객체 지향한다. 당신은 몇 가지가 있다는 사실이 마음에 들지 않는다면 plt그것에는 사용 from matplotlib.artist import setp; setp(ax.get_xticklabels(), rotation=90)대신.
— ImportanceOfBeingErnest

@ImportanceOfBeingErnest 첫 번째 코드 행 plt.xticks은 pyplot입니다. 문서 자체는 스타일을 섞지 말라고 말합니다. plt.setp좀 더 장황하지만 일반적인 객체 지향 스타일은 아닙니다. 당신의 대답은 확실히 여기 최고입니다. 기본적으로 함수가있는 것은 객체 지향이 아닙니다. 수입 여부는 중요하지 setp않습니다.
— Ted Petrou

질문 코드의 대부분은 pyplot과 같은 코드를 사용 yticks하며 코드 외부에 도끼가 정의되어 있지 않습니다 avail_plot.
— cge

113

matplotlib 2.1 이상에서 작동하는 솔루션

tick_params눈금 속성을 변경할 수 있는 좌표축 메서드 가 있습니다. 또한 축 방법으로 존재합니다set_tick_params

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

또는

ax.xaxis.set_tick_params(rotation=45)

참고로, 현재 솔루션은 명령을 사용하여 상태 기반 인터페이스 (pyplot 사용)와 객체 지향 인터페이스를 혼합합니다 plt.xticks(rotation=70). 문제의 코드는 객체 지향 접근 방식을 사용하므로 전체적으로 해당 접근 방식을 따르는 것이 가장 좋습니다. 이 솔루션은 다음과 같은 명시 적 솔루션을 제공합니다.plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )


모든 플롯의 기본 회전을 변경할 수 있습니까? 나는 내가 만드는 모든 줄거리에서 이것을 변경해야한다고 생각합니다.
— Chogg

42

간질을 반복하는 것을 피하는 쉬운 해결책은 바로 사용하는 것입니다

fig.autofmt_xdate()

이 명령은 xaxis 레이블을 자동으로 회전시키고 위치를 조정합니다. 기본값은 회전 각도 30 ° 및 수평 정렬 "오른쪽"입니다. 그러나 함수 호출에서 변경 될 수 있습니다

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

추가 bottom인수는 setting과 동일하며 plt.subplots_adjust(bottom=bottom), 회전 축 눈금 레이블을 호스팅하기 위해 하단 축 패딩을 더 큰 값으로 설정할 수 있습니다.

기본적으로 여기에는 하나의 명령으로 멋진 날짜 축을 갖는 데 필요한 모든 설정이 있습니다.

좋은 예는 하기 matplotlib 페이지에서 확인할 수 있습니다.


좋은 답변입니다! 감사!
— Abramodj

이 기능을 통해 'rotation_mode'파라미터를 제어 할 수 있습니까?
— TheoryX

1
@TheoryX 아니요. rotation_mode가 필요한 경우 plt.setp접근 방식을 사용 하거나 진드기를 반복 해야합니다 (기본적으로 동일 함).
— ImportanceOfBeingErnest

예, x 축이 그래프의 맨 아래에있을 때만 쉬운 해결책입니다. 그러나 x 축이 그래프의 맨 위에 있거나 두 개의 x 축 ( twinx)이 있으면 눈금과 눈금 레이블 간의 정렬을 망칩니다. 이 경우 Ted Petrou의 솔루션이 더 좋습니다.
— Śubham

@ Śubham 맞습니다. 이것은 주로 가장 일반적인 경우에 대한 다른 모든 솔루션에 대한 바로 가기입니다.
— ImportanceOfBeingErnest

18

각 눈금 레이블 을 적용 horizontalalignment하고 적용하는 또 다른 방법 rotation은 for변경하려는 눈금 ​​레이블을 반복하는 것입니다.

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 range(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")

여기에 이미지 설명을 입력하십시오

다음은 주 눈금과 부 눈금의 위치를 ​​제어하려는 경우의 예입니다.

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 range(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")

여기에 이미지 설명을 입력하십시오


1
이것은 (이유는 묻지 말아요 내가 직장에서하기 matplotlib의 기존 버전에 붙어)하기 matplotlib의 v1.5.1에 나를 위해 일한
— 에디

방금 python3.6 및 matplotlib v2.2.2로 테스트했으며 작동합니다.
— Pablo Reyes

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.