[英]Matplotlib bar graph x axis won't plot string values
我叫大衛,我在佛羅里達州的一家救護車服務部門工作。
我正在使用 Python 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()
上面顯示的代碼效果很好。 它返回一個漂亮的圖表,我很高興。 我只想做一個改變。
X 軸不顯示星期幾的名稱,例如“星期日”,而是顯示整數。 換句話說,星期日是 1,星期一是 2,等等。
我對此的解決方法是重寫我的 sql 查詢以使用DATENAME()
而不是DATEPART()
。 下面顯示的是我的 sql 代碼,用於返回星期的名稱(而不是整數)。
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)
我的 Python 代碼中的其他所有內容都保持不變。 但是,這不起作用,我無法理解錯誤消息。
以下是錯誤消息:
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
我無法弄清楚這一點。
總而言之,當我將數據輸出為 x 軸代表星期幾的整數和 y 軸顯示救護車事故數量的計數時,Matplotlib 將生成一個很好的圖表。 但是當我的數據輸出是 x 軸是一個字符串(星期日、星期一等)。 那么 Matplotlib 將不起作用。
我在谷歌上做了幾個小時的研究並閱讀了 matplotlib 文檔。 請幫我解決一下這個。 我希望使用 Matplotlib 作為我的報告引擎。
您的問題與 SQL 查詢無關,它只是一種結束方式。 您真正要問的是如何更改 pylab 中條形圖上的文本標簽。 條形圖的文檔對於自定義很有用,但在這里簡單地更改標簽是一個最小的工作示例 (MWE):
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()
不要僅僅為了改變插圖而更改您的 SQL 代碼。 相反,在您的 Python 代碼中添加一些小內容。
我相信你可以做這樣的回答。 將刻度標簽設置為星期幾。
它可能就像添加以下行一樣簡單:
plt.xticks((1, 2, ..., 7), ('Sunday', 'Monday', ..., 'Saturday'))
編輯:使用一個虛構的表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)
解決問題的最終完成答案:非常感謝史蒂夫。 你幫了大忙。 我在大學里學的是地理,不是編程,所以這對我來說很困難。 這是對我有用的最終代碼。
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()
我不太明白“results=cursor.fetchall()”和以下涉及創建數組的四行代碼之間的界限。 我很高興你這樣做了,因為我看着它,它仍然沒有陷入。非常感謝你。 這有很大幫助。 大衛
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.