복붙노트

[PYTHON] matplotlib의 날짜 틱 및 회전

PYTHON

matplotlib의 날짜 틱 및 회전

matplotlib에서 날짜 틱을 회전시키려는 쟁점이 있습니다. 작은 샘플 프로그램이 아래에 있습니다. 끝에 틱을 회전하려고하면 틱이 회전하지 않습니다. '충돌'주석 아래에 표시된대로 틱을 회전하려고하면 matplot lib가 충돌합니다.

x 값이 날짜 인 경우에만 발생합니다. 변수 날짜를 avail_plot에 대한 호출에서 변수 t로 바꾸면 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()

해결법

  1. ==============================

    1.비 객체 지향 접근법을 선호한다면 두 avail_plot 호출 전에 plt.xticks (rotation = 70)를 오른쪽으로 이동하십시오.

    비 객체 지향 접근법을 선호한다면 두 avail_plot 호출 전에 plt.xticks (rotation = 70)를 오른쪽으로 이동하십시오.

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

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

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

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

    두 avail_plot 호출 후. 이렇게하면 올바른 축의 회전이 구체적으로 설정됩니다.

  2. ==============================

    2.솔루션은 matplotlib 2.1+

    솔루션은 matplotlib 2.1+

    틱 속성을 변경할 수있는 axes 메서드 tick_params가 있습니다. 또한 set_tick_params처럼 축 방법으로 존재합니다

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

    또는

    ax.xaxis.set_tick_params(rotation=45)
    

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

  3. ==============================

    3.ticklabes를 반복하는 것을 피하는 쉬운 해결책은

    ticklabes를 반복하는 것을 피하는 쉬운 해결책은

    fig.autofmt_xdate ()

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

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

    추가적인 bottom 인수는 plt.subplots_adjust (bottom = bottom) 설정과 동일합니다. 회전 된 ticklabels를 호스트하기 위해 하단 축 패딩을보다 큰 값으로 설정할 수 있습니다.

    그래서 기본적으로 여기에는 단일 명령으로 멋진 날짜 축을 갖기 위해 필요한 모든 설정이 있습니다.

    좋은 예가 matplotlib 페이지에서 찾을 수 있습니다.

  4. ==============================

    4.각 눈금 레이블에 수평 정렬과 회전을 적용하는 또 다른 방법은 변경하려는 눈금 ​​레이블 위에 for 루프를 수행하는 것입니다.

    각 눈금 레이블에 수평 정렬과 회전을 적용하는 또 다른 방법은 변경하려는 눈금 ​​레이블 위에 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 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")
    

    주 틱과 마이너 틱의 위치를 ​​제어하려면 다음과 같은 예가 있습니다.

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

  5. from https://stackoverflow.com/questions/11264521/date-ticks-and-rotation-in-matplotlib by cc-by-sa and MIT license