Matplotlib'de tarih keneleri ve döndürme


175

Ben tarih keneler matplotlib döndürülmüş almaya çalışırken bir sorun yaşıyorum. Küçük bir örnek program aşağıdadır. Keneleri sonunda döndürmeye çalışırsam, keneler döndürülmez. Keneleri yorum 'çöküyor' altında gösterildiği gibi döndürmeye çalışırsam, matplot lib çöker.

Bu yalnızca x-değerleri tarih olduğunda gerçekleşir. Ben değişkeni yerini aldıysa datesdeğişkenle tçağrısında avail_plot, xticks(rotation=70)çağrı gayet güzel içini çalışır avail_plot.

Herhangi bir fikir?

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 ekseninde tarihleri ​​olan bir arsa oluşturmak çok yaygın bir iştir - orada daha eksiksiz örnekler yoktur.
alexw

Yanıtlar:


249

Nesne yönelimli olmayan bir yaklaşımı tercih ederseniz , iki aramadan önceplt.xticks(rotation=70) sağa gidin , ör.avail_plot

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

Bu, etiketleri ayarlamadan önce rotation özelliğini ayarlar. Burada iki ekseniniz olduğu plt.xticksiçin, iki parsel yaptıktan sonra karışır. Noktada plt.xticksbir şey yapmaz, plt.gca()gelmez değil bu kadar değiştirmek istediğiniz eksenleri ve vermek plt.xticks, işe gitmiyor cari eksenlerde hareket eder.

Kullanılmayan nesne yönelimli bir yaklaşım için plt.xticksşunları kullanabilirsiniz:

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

iki avail_plotçağrıdan sonra . Bu, dönüşü özel olarak doğru eksenler üzerinde ayarlar.


11
Bir başka kullanışlı şey: plt.setparadığınızda, birden fazla parametreyi ek anahtar kelime bağımsız değişkenleri olarak belirleyerek ayarlayabilirsiniz. horizontalalignment: Eğer kene etiketleri döndürdüğünüzde kwarg özellikle yararlıdırplt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70, horizontalalignment='right' )
8one6

33
Pyplot ve nesne yönelimli yaklaşımları karıştırdığı için bu çözümü sevmiyorum. İstediğiniz ax.tick_params(axis='x', rotation=70)yerden arayabilirsiniz .
Ted Petrou

3
@TedPetrou Burada "karıştırarak" ne demek istiyorsun? plt.setpÇözelti tamamen nesne olup. pltİçinde bazılarının olduğu gerçeğinden hoşlanmıyorsanız, from matplotlib.artist import setp; setp(ax.get_xticklabels(), rotation=90)bunun yerine kullanın.
ImportanceOfBeingErnest

@ImportanceOfBeingErnest pyplot olan ilk kod satırı kullanılır plt.xticks. Belgelerin kendisi stilleri karıştırmamayı söylüyor. plt.setpdaha ayrıntılı ama tipik nesne yönelimli stil de değil. Cevabınız kesinlikle en iyisi. Temel olarak, işlevi olan herhangi bir şey nesne yönelimli değildir. İçe aktarıp aktarmamanız önemli setpdeğildir.
Ted Petrou

Sorunun kodunun çoğu gibi pyplot kullanır yticksve kodun dışında hiç tanımlanmamış balta yoktur avail_plot...
cge

115

Matplotlib 2.1+ için çözüm çalışmaları

tick_paramsKene özelliklerini değiştirebilen bir eksen yöntemi vardır. Ayrıca bir eksen yöntemi olarak varset_tick_params

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

Veya

ax.xaxis.set_tick_params(rotation=45)

Bir yan not olarak, geçerli çözüm, durumsal arabirimi (pyplot kullanarak) komutu kullanarak nesne yönelimli arabirimle karıştırır plt.xticks(rotation=70). Söz konusu kod nesne yönelimli yaklaşımı kullandığından, bu yaklaşıma bağlı kalmak en iyisidir. Çözüm,plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )


Tüm grafikler için varsayılan dönüşü değiştirmek mümkün müdür? Sanırım yaptığım her arsada bunu değiştirmem gerekiyor.
Chogg

42

Ticklabes üzerinde döngüden kaçınmak kolay bir çözüm sadece kullanmaktır

fig.autofmt_xdate()

Bu komut, xaxis etiketlerini otomatik olarak döndürür ve konumlarını ayarlar. Varsayılan değerler 30 ° dönüş açısı ve "sağ" yatay hizalamadır. Ancak fonksiyon çağrısında değiştirilebilirler

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

Ek bottomargüman, plt.subplots_adjust(bottom=bottom)döndürülmüş bilet etiketlerini barındırmak için alt eksen dolgusunun daha büyük bir değere ayarlanmasına izin veren ayara eşdeğerdir .

Temel olarak burada tek bir komutta güzel bir tarih ekseni olması için gereken tüm ayarlara sahipsiniz.

Bir iyi bir örnek matplotlib sayfasında bulunabilir.


Mükemmel cevap! Teşekkürler!
Abramodj

'rotation_mode' parametresini bu işlevle kontrol edebilir misiniz?
TheoryX

1
@TheoryX Hayır. Rotation_mode öğesine ihtiyacınız varsa, plt.setpyaklaşımı kullanmanız veya keneler üzerinde döngü (esas olarak aynıdır) gerekir.
ImportanceOfBeingErnest

Evet, yalnızca grafiğin altında bulunan x ekseni olduğunda kolay bir çözümdür. Ancak, x ekseni grafiğin üstünde olduğunda veya iki x ekseni ( twinx) mevcut olduğunda, keneler ve onay etiketleri arasındaki hizalamayı vidalar. Bu durumda, Ted Petrou'nun çözümü daha iyidir.
hamubham

@ Śubham Doğru. Bu, en yaygın durum için diğer tüm çözümlerin kısayoludur.
ImportanceOfBeingErnest

18

Uygulamanın horizontalalignmentve rotationher bir onay etiketine uygulamak için başka bir yol for, değiştirmek istediğiniz onay etiketleri üzerinde bir döngü yapmaktır:

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

resim açıklamasını buraya girin

Ve büyük ve küçük kenelerin yerini kontrol etmek istiyorsanız bir örnek:

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

resim açıklamasını buraya girin


1
Bu benim için matplotlib v1.5.1'de çalıştı (iş yerinde matplotlib'in eski bir versiyonuna takılı kaldım, nedenini sorma)
Eddy

Ben sadece python3.6 ve matplotlib v2.2.2 ile test ettim ve o da işe yarıyor.
Pablo Reyes

3

Basitçe kullanın

ax.set_xticklabels(label_list, rotation=45)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.