Подтвердить что ты не робот

Графа графа Matplotlib x не будет отображать строковые значения

Меня зовут Дэвид, и я работаю в службе скорой помощи во Флориде.

Я использую 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 не будет работать.

Я провел несколько часов исследований в Google и прочитал документацию matplotlib. Пожалуйста, помогите мне с этим. Я надеюсь использовать Matplotlib в качестве механизма отчетов.

4b9b3361

Ответ 1

Ваш вопрос не имеет ничего общего с 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()

enter image description here

Ответ 2

Не изменяйте свой код SQL, чтобы изменить иллюстрацию. Вместо этого сделайте небольшое дополнение к вашему коду Python.

Я считаю, что вы можете сделать что-то вроде этого ответа. Установите метки меток как дни недели.

Это может быть так же просто, как добавить следующую строку:

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

Документация: pyplot.xticks

EDIT: пример в ответ на комментарий с использованием вымышленной таблицы 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)

Ответ 3

Окончательный ответ, который разрешил проблему: Большое спасибо Стиву. Вы очень помогли. Я изучал географию в колледже, а не программировал, так что это довольно сложно для меня. Вот последний код, который работает для меня.

 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()" и следующими четырьмя строками кода, которые включают создание массивов. Я рад, что вы это делаете, потому что я смотрю на него, и он все еще не погружается. Большое спасибо. Это очень помогает. Дэвид