Matplotlib में डेट टिक और रोटेशन


175

मैं एक मुद्दा मेरी matlotlib में घुमाए गए दिनांक प्राप्त करने की कोशिश कर रहा हूँ। एक छोटा सा नमूना कार्यक्रम नीचे है। अगर मैं अंत में टिक्स को घुमाने की कोशिश करता हूं, तो टिक्कियां घूमती नहीं हैं। अगर मैं टिप्पणी 'दुर्घटनाओं' के तहत दिखाए गए अनुसार टिक्स को घुमाने की कोशिश करता हूं, तो मैटलॉट लिबास क्रैश हो जाता है।

यह केवल तभी होता है यदि 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
एक्स-एक्सिस पर तारीखों के साथ एक प्लॉट बनाना इतना सामान्य काम है - वहाँ एक शर्म की बात नहीं है।
अलेक्सव

अगर यह नहीं का डुप्लिकेट है मैं सोच रहा हूँ stackoverflow.com/questions/10998621/...
ImportanceOfBeingErnest

जवाबों:


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
मुझे यह समाधान पसंद नहीं है क्योंकि यह पाइलट और ऑब्जेक्ट-ओरिएंटेड एप्रोच को मिलाता है। आप ax.tick_params(axis='x', rotation=70)किसी भी स्थान पर कॉल कर सकते हैं ।
टेड पेट्रोउ

3
@TedPetrou यहाँ "मिश्रण" से आपका क्या मतलब है? plt.setpसमाधान पूरी तरह से उन्मुख वस्तु है। यदि आपको यह तथ्य पसंद नहीं है कि इसमें कुछ pltहै, तो from matplotlib.artist import setp; setp(ax.get_xticklabels(), rotation=90)इसके बजाय उपयोग करें ।
ImportanceOfBeingErnest

@ImportanceOfBeingErnest कोड की पहली पंक्ति में pyplot का उपयोग plt.xticksकिया गया है। प्रलेखन स्वयं शैलियों को मिश्रण नहीं करने के लिए कहता है। plt.setpअधिक क्रिया है लेकिन विशिष्ट वस्तु-उन्मुख शैली भी नहीं है। आपका उत्तर निश्चित रूप से यहाँ सबसे अच्छा है। मूल रूप से, एक फ़ंक्शन के साथ कुछ भी वस्तु-उन्मुख नहीं है। इससे कोई फर्क नहीं पड़ता कि आप आयात करते हैं setpया नहीं।
टेड पेट्रोउ

प्रश्न का अधिकांश कोड 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 )


क्या सभी भूखंडों के लिए डिफ़ॉल्ट रोटेशन को बदलना संभव है? मुझे लगता है कि मुझे अपने द्वारा किए गए हर प्लॉट पर इसे बदलने की जरूरत है।
चोगीग

42

एक आसान समाधान जो टिक्कबल्स पर लूपिंग से बचा जाता है, बस उपयोग करना है

fig.autofmt_xdate()

यह कमांड स्वचालित रूप से xaxis लेबल को घुमाती है और उनकी स्थिति को समायोजित करती है। डिफ़ॉल्ट मान एक रोटेशन कोण 30 ° और क्षैतिज संरेखण "सही" हैं। लेकिन उन्हें फंक्शन कॉल में बदला जा सकता है

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

अतिरिक्त bottomतर्क सेटिंग के बराबर है plt.subplots_adjust(bottom=bottom), जो घुमाए गए टिकलैबल्स को होस्ट करने के लिए नीचे के कुल्हाड़ियों को बड़े मूल्य पर सेट करने की अनुमति देता है।

तो मूल रूप से यहां आपके पास सभी सेटिंग्स हैं जिनकी आपको एक ही कमांड में एक अच्छी तारीख की धुरी है।

एक अच्छा उदाहरण matplotlib पेज पर पाया जा सकता है।


बहुत बढ़िया जवाब! धन्यवाद!
अब्रामोदज

क्या आप इस फ़ंक्शन के माध्यम से 'रोटेशन_मोड' पैरामीटर को नियंत्रित कर सकते हैं?
थ्योरीएक्स

1
@ थ्योरीएक्स नंबर यदि आपको रोटेशन_मोड की आवश्यकता है, तो आपको या तो plt.setpदृष्टिकोण का उपयोग करने की आवश्यकता है , या टिक्सेस पर लूप (जो अनिवार्य रूप से समान है)।
महत्व

हाँ, यह केवल एक आसान समाधान है जब x अक्ष ग्राफ के तल पर मौजूद होता है। हालाँकि, जब x अक्ष ग्राफ के शीर्ष पर होता है या जब दो x axes ( twinx) मौजूद होते हैं, तो यह टिक और टिक लेबल के बीच संरेखण को बढ़ा देता है। उस मामले में, टेड पेट्रो द्वारा समाधान बेहतर है।
शुभम

@ Ś शुभम सही यह मुख्य रूप से सबसे आम मामले के लिए अन्य सभी समाधानों का शॉर्टकट है।
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 v1.5.1 पर काम कर रहा है (मैं काम पर matplotlib के विरासत संस्करण पर अटका हुआ हूं, यह मत पूछें क्यों)
एड़ी

मैं सिर्फ python3.6 और matplotlib v2.2.2 के साथ परीक्षण किया है और यह भी काम करता है।
पाब्लो रेयेस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.