2012-05-16 15 views
18

मैं एक ग्राफ तैयार करने की कोशिश कर रहा हूं और मुझे कुछ समस्याएं बता रही हैं।Matplotlib: स्ट्रिंग को कस्टम एक्स-टिक के रूप में जोड़ें लेकिन मौजूदा (संख्यात्मक) टिक लेबल भी रखें? Matplotlib.pyplot.annotate के विकल्प?

मेरे ग्राफ में एक्स-अक्ष पर एक लॉग स्केल है, जो समय दिखा रहा है। मैं जो करने में सक्षम होना चाहता हूं वह मौजूदा (लेकिन अनुमानित नहीं) संख्यात्मक टिक लेबल 100 इकाइयों, 1000 इकाइयों, 10000 इकाइयों आदि पर रखता है, लेकिन एक्स-अक्ष में कस्टम टिक लेबल भी जोड़ता है जो इसे स्पष्ट करता है कि "मानव" पठनीय "समय अंतराल होता है --- उदाहरण के लिए मैं 'एक सप्ताह', 'एक महीने', '6 महीने', आदि

लेबल करने में सक्षम होना चाहता हूं, मैं matplotlib.pyplot.annotate() को चिह्नित करने के लिए उपयोग कर सकता हूं अंक लेकिन यह वास्तव में वह नहीं करता जो मैं चाहता हूं। मैं वास्तव में अपने ग्राफ के शीर्ष पर पाठ और तीर नहीं चाहता हूं, मैं बस कुछ अतिरिक्त कस्टम टिक अंक जोड़ना चाहता हूं। कोई विचार?

उत्तर

16

तुम सच में जोड़ना चाहते हैं अतिरिक्त टिक, आप axis.xaxis.get_majorticklocs() का उपयोग कर मौजूदा लोगों को प्राप्त कर सकते हैं, जो भी आप जोड़ना चाहते हैं उसे जोड़ें, और फिर axis.xaxis.set_ticks(<your updated array>) का उपयोग करके टिक सेट करें।

एक विकल्प लंबवत रेखा using axvline जोड़ने के लिए होगा। लाभ यह है कि आपको मौजूदा सरणी में अपनी कस्टम टिक डालने के बारे में चिंता करने की ज़रूरत नहीं है, लेकिन आपको मैन्युअल रूप से लाइनों को एनोटेट करना होगा।

फिर भी एक और विकल्प आपके कस्टम टिक के साथ एक लिंक किए गए अक्ष को जोड़ना होगा।

+1

धन्यवाद। मुझे लगता है कि यह एक माध्यमिक एक्स-अक्ष जोड़ने के लिए और अधिक समझ में आता है। संख्यात्मक और स्ट्रिंग अक्ष लेबल को मिलाकर परेशान ओवरलैप और स्वरूपण समस्याएं होती हैं, इसलिए मैं केवल जुड़वां() के साथ जाऊंगा। :-) – FakeDIY

+1

इस प्रश्न से आपके लिए उपयोग किया जा सकता है: http://stackoverflow.com/questions/10514315/how-to-add-a-second-x-axis-in-matplotlib –

12

http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.xticks से:

# return locs, labels where locs is an array of tick locations and 
# labels is an array of tick labels. 
locs, labels = xticks() 

तो तुम सब करने की जरूरत है चाहिए locs और labels और उसके बाद संशोधित labels अपनी पसंद के अनुसार प्राप्त है (डमी उदाहरण):

labels = ['{0} (1 day)','{0} (1 weak)', '{0} (1 year)'] 
new_labels = [x.format(locs[i]) for i,x in enumerate(labels)] 

और उसके बाद चलाएँ:

xticks(locs, new_labels) 
+0

यह काम करता है, लेकिन यह काफी नहीं है जो मैं करना चाहता हूं। मैं देख सकता हूं कि मैं अंततः वांछित परिणाम प्राप्त करने के लिए xticks() का उपयोग कर सकता हूं, लेकिन मुझे लगता है कि यह वास्तव में नीचे वर्णित एक दूसरी एक्स-अक्ष को साजिश करने के लिए स्वच्छ और आसान होगा। धन्यवाद। – FakeDIY

+0

ठीक है, तो आपको वह जवाब स्वीकार करना चाहिए। मैं मानता हूं कि यह एक हैक का अधिक है (लेकिन घर के उपयोग/त्वरित सुधार के लिए काम करता है)। – deinonychusaur

5

यह मेरा समाधान है। मुख्य लाभ हैं:

  • आप कुल्हाड़ियों निर्दिष्ट कर सकते हैं
  • आप अक्ष निर्दिष्ट कर सकते हैं (पुट x- अक्ष या y- अक्ष पर टिक्स)
  • (जुड़वां कुल्हाड़ियों के लिए या यदि उपयोगी एक साथ कई कुल्हाड़ियों के साथ काम)
  • आप स्वचालित रूप से
  • रखते हुए आसानी से नई टिक जोड़ सकते हैं यदि आप पहले से मौजूद एक टिक जोड़ते हैं तो यह स्वचालित रूप से बदल जाता है।

कोड:

#!/usr/bin/python 
from __future__ import division 
import matplotlib.pyplot as plt 
import numpy as np 

#Function to add ticks 
def addticks(ax,newLocs,newLabels,pos='x'): 
    # Draw to get ticks 
    plt.draw() 

    # Get existing ticks 
    if pos=='x': 
     locs = ax.get_xticks().tolist() 
     labels=[x.get_text() for x in ax.get_xticklabels()] 
    elif pos =='y': 
     locs = ax.get_yticks().tolist() 
     labels=[x.get_text() for x in ax.get_yticklabels()] 
    else: 
     print("WRONG pos. Use 'x' or 'y'") 
     return 

    # Build dictionary of ticks 
    Dticks=dict(zip(locs,labels)) 

    # Add/Replace new ticks 
    for Loc,Lab in zip(newLocs,newLabels): 
     Dticks[Loc]=Lab 

    # Get back tick lists 
    locs=list(Dticks.keys()) 
    labels=list(Dticks.values()) 

    # Generate new ticks 
    if pos=='x': 
     ax.set_xticks(locs) 
     ax.set_xticklabels(labels) 
    elif pos =='y': 
     ax.set_yticks(locs) 
     ax.set_yticklabels(labels) 


#Get numpy arrays 
x=np.linspace(0,2) 
y=np.sin(4*x) 

#Start figure 
fig = plt.figure() 
ax=fig.add_subplot(111) 

#Plot Arrays 
ax.plot(x,y) 
#Add a twin axes 
axr=ax.twinx() 

#Add more ticks 
addticks(ax,[1/3,0.75,1.0],['1/3','3/4','Replaced']) 
addticks(axr,[0.5],['Miguel'],'y') 

#Save figure 
plt.savefig('MWE.pdf') 
1

मैं ऊपर मिगुएल के जवाब की तरह। काफी अच्छी तरह से काम किया। हालांकि, एक छोटा समायोजन किया जाना है। निम्नलिखित:

# Get back tick lists 
locs=Dticks.keys() 
labels=Dticks.values() 

के बाद से, +/3

# Get back tick lists 
locs=list(Dticks.keys()) 
labels=list(Dticks.values()) 

लिए परिवर्तित किया जाना चाहिए अजगर 2.7 में, Dict.keys() और Dict.values ​​() वापसी dict_keys और dict_values ​​वस्तुओं, matplotlib करता है जो पसंद नहीं (जाहिर है)। PEP 3106 में उन दो वस्तुओं के बारे में अधिक जानकारी।

+0

धन्यवाद, मैंने आपका सुझाव जोड़ा मेरे जवाब में। – Miguel