2012-02-01 8 views
27

मेरा नाम डेविड है और मैं फ्लोरिडा में एम्बुलेंस सेवा के लिए काम करता हूं।Matplotlib बार ग्राफ x अक्ष स्ट्रिंग मानों को प्लॉट नहीं करेगा

मैं अजगर 2.7 और matplotlib उपयोग कर रहा हूँ। मैं एम्बुलेंस कॉल के अपने डेटाबेस में पहुंचने का प्रयास कर रहा हूं और प्रत्येक सप्ताह के दिन होने वाली कॉल की संख्या को गिनता हूं।

मैं तो इस जानकारी में से एक बार चार्ट बनाने के लिए सहयोगी कैसे व्यस्त वे प्रत्येक दिन पर हैं का एक दृश्य ग्राफिक देने के लिए matplotlib का प्रयोग करेंगे।

import pyodbc 
import matplotlib.pyplot as plt 
MySQLQuery = """ 
SELECT 
DATEPART(WEEKDAY, IIU_tDispatch)AS [DayOfWeekOfCall] 
, COUNT(DATEPART(WeekDay, IIU_tDispatch)) AS [DispatchesOnThisWeekday] 
FROM AmbulanceIncidents 
GROUP BY DATEPART(WEEKDAY, IIU_tDispatch) 
ORDER BY DATEPART(WEEKDAY, IIU_tDispatch) 
""" 
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=MyServer;DATABASE=MyDatabase;UID=MyUserID;PWD=MyPassword') 
cursor = cnxn.cursor() 
GraphCursor = cnxn.cursor() 
cursor.execute(MySQLQuery) 

#generate a graph to display the data 
data = GraphCursor.fetchall() 
DayOfWeekOfCall, DispatchesOnThisWeekday = zip(*data) 
plt.bar(DayOfWeekOfCall, DispatchesOnThisWeekday) 
plt.grid() 
plt.title('Dispatches by Day of Week') 
plt.xlabel('Day of Week') 
plt.ylabel('Number of Dispatches') 
plt.show() 

ऊपर दिखाए गए कोड बहुत अच्छी तरह से काम करता है:

कोड यहां जो बहुत अच्छी तरह काम करती है। यह एक अच्छा दिखने वाला ग्राफ देता है और मैं खुश हूं। मैं बस एक बदलाव करना चाहता हूँ।

एक्स इस तरह के "रविवार" के रूप में सप्ताह के दिन के नाम दिखा अक्ष के बजाय

, यह पूर्णांक को दर्शाता है। दूसरे शब्दों में, रविवार 1 है, सोमवार 2 है, आदि

इस के लिए मेरे ठीक है कि मैं DATENAME() का उपयोग करने के बजाय DatePart की() मेरी एसक्यूएल क्वेरी पुनर्लेखन है। नीचे दिखाया गया है मेरा एसक्यूएल कोड सप्ताह के नाम को वापस करने के लिए (एक पूर्णांक के विपरीत)।

SELECT 
DATENAME(WEEKDAY, IIU_tDispatch)AS [DayOfWeekOfCall] 
, COUNT(DATENAME(WeekDay, IIU_tDispatch)) AS [DispatchesOnThisWeekday] 
FROM AmbulanceIncidents 
GROUP BY DATENAME(WEEKDAY, IIU_tDispatch) 
ORDER BY DATENAME(WEEKDAY, IIU_tDispatch) 

मेरे पायथन कोड में बाकी सब कुछ वही रहता है। हालांकि यह काम नहीं करेगा और मैं त्रुटि संदेशों को समझ नहीं सकता।

Traceback (most recent call last): 
    File "C:\Documents and Settings\kulpandm\workspace\FiscalYearEndReport\CallVolumeByDayOfWeek.py", line 59, in 

<module> 
    plt.bar(DayOfWeekOfCall, DispatchesOnThisWeekday) 
    File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 2080, in bar 
    ret = ax.bar(left, height, width, bottom, **kwargs) 
    File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 4740, in bar 
    self.add_patch(r) 
    File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 1471, in add_patch 
    self._update_patch_limits(p) 
    File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 1489, in _update_patch_limits 
    xys = patch.get_patch_transform().transform(vertices) 
    File "C:\Python27\lib\site-packages\matplotlib\patches.py", line 547, in get_patch_transform 
    self._update_patch_transform() 
    File "C:\Python27\lib\site-packages\matplotlib\patches.py", line 543, in _update_patch_transform 
    bbox = transforms.Bbox.from_bounds(x, y, width, height) 
    File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 745, in from_bounds 
    return Bbox.from_extents(x0, y0, x0 + width, y0 + height) 
TypeError: coercing to Unicode: need string or buffer, float found 

मैं इस को समझ नहीं सकता:

यहाँ त्रुटि संदेश है।

समेट करने के लिए, जब मैं एक्स अक्ष के साथ अपने डेटा को सप्ताह के दिनों का प्रतिनिधित्व करने वाले पूर्णांक के रूप में आउटपुट करता हूं और वाई अक्ष एम्बुलेंस घटनाओं की संख्या की गणना दिखाता है, तो मैटलप्लिब एक अच्छा ग्राफ उत्पन्न करेगा। लेकिन जब मेरा डेटा आउटपुट एक्स अक्ष एक स्ट्रिंग (रविवार, सोमवार, आदि) है। तो Matplotlib काम नहीं करेगा।

मैं गूगल पर अनुसंधान और matplotlib प्रलेखन पढ़ने के कई घंटे किया है। कृपया इसके साथ मेरी मदद करें। मैं अपने रिपोर्ट इंजन के रूप में Matplotlib का उपयोग करने की उम्मीद कर रहा हूँ।

उत्तर

6

चित्रण को बदलने के लिए बस अपना SQL कोड बदलें न बदलें। इसके बजाय, अपने पायथन कोड में एक छोटा सा अतिरिक्त करें।

मैं तुम्हें this answer की तरह कुछ कर सकते हैं विश्वास करते हैं। सप्ताह के दिनों के लिए टिक लेबल सेट करें।

यह निम्न पंक्ति जोड़कर के रूप में सरल हो सकता है:

plt.xticks((1, 2, ..., 7), ('Sunday', 'Monday', ..., 'Saturday')) 

Documentation: pyplot.xticks

संपादित करें: जवाब में उदाहरण एक काल्पनिक तालिका IncidentTypes उस घटना के प्रकार के नाम के पूर्णांक कुंजी के नक्शे का उपयोग कर टिप्पणी करने के लिए।

cursor.execute('select incident_type_id, count(*), incident_type 
    from Incidents join IncidentTypes using (incident_type_id) 
    group by incident_type_id') 
results = cursor.fetchall() 
tickpositions = [int(r[0]) for r in results] 
numincidents = [int(r[1]) for r in results] 
ticklabels = [r[2] for r in results] 

plt.bar(tickpositions, numincidents) 
plt.xticks(tickpositions, ticklabels) 
+0

यह लगता है कि यह एक अच्छा जवाब हो सकता है। मैं अभी इसे आजमाने की कोशिश कर रहा हूं। दुर्भाग्यवश, अगले बार ग्राफ को बनाने की आवश्यकता है, जो कि एम्बुलेंस की घटनाओं के प्रकारों की संख्या है। लगभग 60 विभिन्न प्रकार की घटनाएं हैं। मैं एक्स अक्ष के लिए 60 विभिन्न प्रकार के मानों को हार्ड कोड नहीं कर सकता। यह सिर्फ त्रुटि के लिए प्रवण है। पिछली पोस्ट से –

+0

निरंतरता। एसपीएसएस और एसएएस आसानी से नाममात्र मूल्यों का उपयोग करके बार चार्ट बनाते हैं। मुझे विश्वास है कि यह Matplotlib के लिए इतना मुश्किल है। कुछ आसान होना है कि मैं याद कर रहा हूँ! लेकिन यह क्या हैं ? –

+0

पुन: पहली टिप्पणी: आप एक SQL तालिका जोड़ सकते हैं जो घटनाओं के लिए दिन या पूर्णांक के पूर्णांक को मैप करता है। उदाहरण: 'तालिका बनाएं घटनाएं टाइप करें (पीके int प्राथमिक कुंजी auto_increment, नाम वर्कर (20)) '। फिर बस टेबल में शामिल हों। यह लचीला और मॉड्यूलर है। आप किसी घटना प्रकार को कुंजी (int) या नाम (पायथन में) से संदर्भित कर सकते हैं। –

1

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

import pyodbc 
    import matplotlib.pyplot as plt 
    MySQLQuery = """ 
    SELECT 
     DATEPART(WEEKDAY, IIU_tDispatch)AS [IntegerOfDayOfWeek] 
    , COUNT(DATENAME(WeekDay, IIU_tDispatch)) AS [DispatchesOnThisWeekday] 
    , DATENAME(WEEKDAY, IIU_tDispatch)AS [DayOfWeekOfCall] 
    FROM IIncidentUnitSummary 
    INNER JOIN PUnit ON IIU_kUnit = PUN_Unit_PK 
    WHERE PUN_UnitAgency = 'LC' 
    AND IIU_tDispatch BETWEEN 'October 1, 2010' AND 'October 1, 2011' 
    AND PUN_UnitID LIKE 'M__' 
    GROUP BY DATEPART(WEEKDAY, IIU_tDispatch), DATENAME(WEEKDAY, IIU_tDispatch) 
    ORDER BY DATEPART(WEEKDAY, IIU_tDispatch) 
    """ 
    cnxn = pyodbc.connect("a bunch of stuff I don't want to share") 
    cursor = cnxn.cursor() 
    GraphCursor = cnxn.cursor() 
    cursor.execute(MySQLQuery) 

    results = cursor.fetchall() 
    IntegerDayOfWeek, DispatchesOnThisWeekday, DayOfWeekOfCall = zip(*results) 
    tickpositions = [int(r[0]) for r in results] 
    numincidents = [int(r[1]) for r in results] 
    ticklabels = [r[2] for r in results] 
    plt.bar(tickpositions, numincidents) 
    plt.xticks(tickpositions, ticklabels) 
    #plt.bar(DayOfWeekOfCall, DispatchesOnThisWeekday) 
    plt.grid() 
    plt.title('Dispatches by Day of Week') 
    plt.xlabel('Day of Week') 
    plt.ylabel('Number of Dispatches') 
    plt.show() 

    cursor.close() 
    cnxn.close() 

मैं वास्तव में के बीच "परिणाम = cursor.fetchall()" और कोड की निम्न चार लाइनें बनाने सरणियों शामिल लाइनों समझ में नहीं आता। मुझे खुशी है कि आप करते हैं, क्योंकि मैं इसे देखता हूं और यह अभी भी डूबता नहीं है। आपको बहुत धन्यवाद। यह बहुत मदद करता है। डेविड

59

आपके प्रश्न के पास SQL ​​क्वेरी के साथ कुछ लेना देना नहीं है, यह केवल समाप्त करने का साधन है। आप वास्तव में क्या पूछ रहे हैं कि पिलैब में बार चार्ट पर टेक्स्ट लेबल्स को कैसे बदला जाए। bar chart के लिये दस्तावेज अनुरूपण के लिए उपयोगी होते हैं, लेकिन बस change the labels करने के लिए यहाँ एक न्यूनतम काम कर उदाहरण (मेगावाट) है:

import pylab as plt 

DayOfWeekOfCall = [1,2,3] 
DispatchesOnThisWeekday = [77, 32, 42] 

LABELS = ["Monday", "Tuesday", "Wednesday"] 

plt.bar(DayOfWeekOfCall, DispatchesOnThisWeekday, align='center') 
plt.xticks(DayOfWeekOfCall, LABELS) 
plt.show() 

enter image description here

+9

क्या किसी और को यह अजीब लगता है कि एक बार चार्ट डिफ़ॉल्ट रूप से स्ट्रिंग लेबल स्वीकार नहीं करता है? – Owen

+1

@ ओवेन। इस बिंदु पर matplotlib इतना अजीब है कि मुझे संदेह है कि कोई भी वास्तव में समझता है कि कुछ भी क्यों होता है। –

+0

@ ओवेन। सौभाग्य से समुद्री तट (हालांकि matplotlib पर बनाया गया) में यह समस्या प्रतीत नहीं होती है (https://stackoverflow.com/q/32528154/4900327)। –

संबंधित मुद्दे