Matplotlib条形图x轴不会绘制字符串值

Dav*_*ski 35 python matplotlib bar-chart

我的名字是大卫,我在佛罗里达州为救护车服务.

我使用的是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()
Run Code Online (Sandbox Code Playgroud)

上面显示的代码非常有效.它返回一个漂亮的图表,我很高兴.我只想做一个改变.

而不是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)
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚这一点.

总而言之,当我用x轴输出我的数据作为表示星期几的整数而y轴显示救护车事件数量的计数时,Matplotlib将产生一个漂亮的图形.但是当我的数据输出是x轴是一个字符串(星期日,星期一等).然后Matplotlib将无法正常工作.

我已经对Google进行了几个小时的研究并阅读了matplotlib文档.请帮我解决一下这个.我希望使用Matplotlib作为我的报告引擎.

Hoo*_*ked 78

您的问题与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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 有没有人觉得条形图默认不接受字符串标签真的很奇怪? (21认同)
  • @Owen.在这一点上matplotlib是如此奇怪,我怀疑没有人真正理解为什么会发生任何事情. (4认同)

Ste*_*joa 6

不要仅仅为了更改插图而更改SQL代码.相反,在Python代码中添加一小部分内容.

我相信你可以做这样的答案.将刻度标签设置为一周中的几天.

它可能像添加以下行一样简单:

plt.xticks((1, 2, ..., 7), ('Sunday', 'Monday', ..., 'Saturday'))
Run Code Online (Sandbox Code Playgroud)

文档: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)
Run Code Online (Sandbox Code Playgroud)