简体   繁体   English

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

[英]Matplotlib bar graph x axis won't plot string values

My name is David and I work for an ambulance service in Florida.我叫大卫,我在佛罗里达州的一家救护车服务部门工作。

I am using Python 2.7 and matplotlib.我正在使用 Python 2.7 和 matplotlib。 I am attempting to reach into my database of ambulance calls and count up the number of calls that happen on each weekday.我试图进入我的救护车呼叫数据库并计算每个工作日发生的呼叫数量。

I will then use matplotlib to create a bar chart of this information to give the paramedics a visual graphic of how busy they are on each day.然后,我将使用 matplotlib 创建此信息的条形图,以便为护理人员提供他们每天的忙碌程度的直观图形。

HERE IS CODE THAT WORKS VERY WELL:这是运行良好的代码:

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()

The code shown above works very well.上面显示的代码效果很好。 It returns a nice looking graph and I am happy.它返回一个漂亮的图表,我很高兴。 I just want to make one change.我只想做一个改变。

Instead of the X axis showing the names of the days of the week, such as "Sunday", it shows the integer. X 轴不显示星期几的名称,例如“星期日”,而是显示整数。 In other words, Sunday is 1, Monday is 2, etc.换句话说,星期日是 1,星期一是 2,等等。

My fix for this is that I rewrite my sql query to use DATENAME() instead of DATEPART() .我对此的解决方法是重写我的 sql 查询以使用DATENAME()而不是DATEPART() Shown below is my sql code to return the name of the week (as opposed to an integer).下面显示的是我的 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)

Everything else in my python code stays the same.我的 Python 代码中的其他所有内容都保持不变。 However this will not work and I cannot understand the error messages.但是,这不起作用,我无法理解错误消息。

Here are the error messages:以下是错误消息:

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

I cannot figure this out.我无法弄清楚这一点。

To sum up, when I output my data with the x axis as integers representing days of week and y axis showing a count of the number of ambulance incidents, Matplotlib will produce a nice graph.总而言之,当我将数据输出为 x 轴代表星期几的整数和 y 轴显示救护车事故数量的计数时,Matplotlib 将生成一个很好的图表。 But when my data output is the x axis is a string (Sunday, Monday, etc).但是当我的数据输出是 x 轴是一个字符串(星期日、星期一等)。 then Matplotlib will not work.那么 Matplotlib 将不起作用。

I have done several hours of research on Google and reading the matplotlib documentation.我在谷歌上做了几个小时的研究并阅读了 matplotlib 文档。 Please help me with this.请帮我解决一下这个。 I am hoping to use Matplotlib as my reports engine.我希望使用 Matplotlib 作为我的报告引擎。

Your question has nothing to do with an SQL query, it is simply a means to end.您的问题与 SQL 查询无关,它只是一种结束方式。 What you are really asking is how to change the text labels on a bar chart in pylab.您真正要问的是如何更改 pylab 中条形图上的文本标签。 The docs for the bar chart are useful for customizing, but to simply change the labels here is a minimal working example (MWE): 条形图的文档对于自定义很有用,但这里简单地更改标签是一个最小的工作示例 (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()

在此处输入图片说明

Don't change your SQL code just to alter the illustration.不要仅仅为了改变插图而更改您的 SQL 代码。 Instead, make a small addition to your Python code.相反,在您的 Python 代码中添加一些小内容。

I believe you can do something like this answer .我相信你可以做这样的回答 Set the tick labels to be the days of the week.将刻度标签设置为星期几。

It may be as simple as adding the following line:它可能就像添加以下行一样简单:

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

Documentation: pyplot.xticks 文档:pyplot.xticks

EDIT: Example in response to comment using a fictional table IncidentTypes that maps integer keys to names of incident types.编辑:使用一个虚构的表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)

Final completed answer that resolved the issue: Thank you very much Steve.解决问题的最终完成答案:非常感谢史蒂夫。 You have been a great help.你帮了大忙。 I studied geography in college, not programming, so this is quite difficult for me.我在大学里学的是地理,不是编程,所以这对我来说很困难。 Here is the final code that works for me.这是对我有用的最终代码。

 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()

I don't really understand the lines between "results=cursor.fetchall()" and the following four lines of code that involve creating arrays.我不太明白“results=cursor.fetchall()”和以下涉及创建数组的四行代码之间的界限。 I am glad you do, because I look at it and it still does not sink in. thank you very much.我很高兴你这样做了,因为我看着它,它仍然没有陷入。非常感谢你。 This helps out a lot.这有很大帮助。 David大卫

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM