2012-02-01 3 views
27

내 이름은 David이고 나는 플로리다에서 구급차 서비스를 위해 일합니다.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() 

: HERE

매우 잘 작동 코드이다. 그것은 멋진 그래프를 반환하고 나는 행복합니다. 나는 단지 하나의 변화를 만들고 싶다.

"Sunday"와 같이 요일의 이름을 나타내는 X 축 대신 정수를 표시합니다. 즉 일요일은 1, 월요일은 2 등입니다.

DATEPART() 대신 DATENAME()을 사용하도록 sql 쿼리를 다시 작성했습니다. 다음은 내 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) 

내 파이썬 코드의 다른 모든 항목은 그대로 유지됩니다. 그러나이 작동하지 않습니다 및 오류 메시지를 이해할 수 없습니다. 나는이 알아낼 수 없습니다

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을 사용하고 싶습니다.

답변

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 가지 유형의 사건이 있습니다. x 축에 대해 60 가지 유형의 값을 하드 코딩 할 수 없습니다. 그것은 단지 오류가 발생하기 쉽습니다. –

+0

이전 게시물에서 계속됩니다. SPSS와 SAS는 공칭 값을 사용하여 막대 차트를 쉽게 생성합니다. 나는 이것이 Matplotlib에게 그렇게 어렵다고 믿기가 힘듭니다. 내가 누락 된 일이 쉬워 져야한다! 그러나 그것은 무엇입니까? –

+0

첫 번째 주석 추가 : 정수를 일 또는 정수를 사건 유형에 매핑하는 SQL 테이블을 추가 할 수 있습니다. 예 :'create table IncidentTypes (pk int 기본 키 auto_increment, Name varchar (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() 

"results = cursor.fetchall()"과 배열 만들기와 관련된 다음 네 줄의 코드 사이의 줄은 실제로 이해할 수 없습니다. 나는 당신을 기쁘게 생각합니다, 왜냐하면 저는 그것을 보았고 여전히 침몰하지 않습니다. 대단히 감사합니다. 이것은 많은 도움이됩니다. David

59

귀하의 질문은 SQL 쿼리와 관련이 없으며 단순히 종료하는 것입니다. 당신이 정말로 묻고있는 것은 파일 랩의 가로 막 대형 차트에서 텍스트 레이블을 변경하는 방법입니다. bar chart에 대한 문서는 사용자 정의 유용하지만 단순히 change the labels 여기에 최소한의 작업 예 (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

+9

막대 그래프가 기본적으로 문자열 레이블을 허용하지 않는다는 것을 알고있는 사람이 있습니까? – Owen

+1

@Owen. 이 시점에서 matplotlib은 너무 이상해서 아무도 실제로 어떤 일이 일어나는지 이해하지 못한다고 생각합니다. –

+0

@Owen. 다행스럽게도 (비록 matplotlib에 내장되어 있지만)이 문제는없는 것 같습니다 (https://stackoverflow.com/q/32528154/4900327). –

관련 문제