2012-02-01 9 views
27

私の名前はDavidです。私はフロリダの救急車サービスの仕事をしています。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() 

:HERE

は非常によく動作するコードです。それは素晴らしいグラフを返し、私は満足しています。私はちょうど1つの変更をしたい。代わりに、このような「日曜日」として曜日の名前を示すX軸の

は、それは整数を示しています。言い換えれば、日曜日はこのため

私の修正は、私が代わりにDATEPARTの())DATENAMEを(使用するように私のSQLクエリを書き直すことであるなど、月曜日は2で、1です。 以下は、整数の代わりに週の名前を返す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 

はここでエラーメッセージが表示されています。

要約すると、救急車のインシデント数を示すy軸と曜日を表す整数としてx軸のデータを出力すると、Matplotlibは素晴らしいグラフを生成します。しかし、私のデータ出力がx軸の場合は文字列(日曜日、月曜日など)です。 Matplotlibは機能しません。

Googleで数時間の研究を行い、matplotlibのドキュメントを読んでいます。 これを手伝ってください。 Matplotlibをレポートエンジンとして使用したいと考えています。

答えて

6

イラストを変更するためだけにSQLコードを変更しないでください。代わりに、あなたのPythonコードに少し追加してください。

私はあなたが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)または名前(Python)で参照できます。 –

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()"と配列の作成に関連する次の4行のコード間の行は実際には分かりません。私はそれを見て、まだ沈んでいないので、あなたがうれしいです。 ありがとうございました。これは多くの助けになります。 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)を持っていないようです。 –

関連する問題