Je m'appelle David et je travaille pour un service d'ambulance en Floride.
J'utilise Python 2.7 et matplotlib. J'essaie d'accéder à ma base de données d'appels d'ambulance et de compter le nombre d'appels qui se produisent chaque jour de semaine.
Je vais ensuite utiliser matplotlib pour créer un graphique à barres de ces informations pour donner aux ambulanciers paramédicaux un graphique visuel de la façon dont ils sont occupés chaque jour.
ICI IS CODE QUI FONCTIONNE TRÈS BIEN:
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()
Le code ci-dessus fonctionne très bien. Il renvoie un joli graphique et je suis heureux. Je veux juste faire un changement.
Au lieu de l'axe X montrant les noms des jours de la semaine, tels que "dimanche", il montre l'entier. En d'autres termes, dimanche est 1, lundi est 2, etc.
Ma solution est que je réécris ma requête SQL pour utiliser DATENAME () au lieu de DATEPART (). Ci-dessous est mon code sql pour retourner le nom de la semaine (par opposition à un entier).
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)
Tout le reste dans mon code python reste le même. Cependant, cela ne fonctionnera pas et je ne peux pas comprendre les messages d'erreur.
Voici les messages d'erreur:
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
Je ne peux pas comprendre cela.
Pour résumer, lorsque je produis mes données avec l'axe x sous forme d'entiers représentant les jours de la semaine et l'axe y montrant un décompte du nombre d'incidents d'ambulance, Matplotlib produira un joli graphique. Mais lorsque ma sortie de données est l'axe des x, c'est une chaîne (dimanche, lundi, etc.). alors Matplotlib ne fonctionnera pas.
J'ai fait plusieurs heures de recherche sur Google et lu la documentation de matplotlib. S'il vous plait, j'ai besoin de votre aide avec ceci. J'espère utiliser Matplotlib comme moteur de rapports.
Votre question n'a rien à voir avec une requête SQL, c'est simplement un moyen de terminer. Ce que vous demandez vraiment, c'est comment changer les étiquettes de texte sur un graphique à barres dans pylab. Les documents pour graphique à barres sont utiles pour la personnalisation, mais simplement changer les étiquettes voici un exemple de travail minimal (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()
Ne modifiez pas votre code SQL juste pour modifier l'illustration. À la place, faites un petit ajout à votre code Python.
Je crois que vous pouvez faire quelque chose comme cette réponse . Définissez les étiquettes des ticks comme étant les jours de la semaine.
Cela peut être aussi simple que d'ajouter la ligne suivante:
plt.xticks((1, 2, ..., 7), ('Sunday', 'Monday', ..., 'Saturday'))
EDIT: Exemple de réponse à un commentaire utilisant une table fictive IncidentTypes
qui mappe les clés entières aux noms des types d'incidents.
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)
Réponse finale terminée qui a résolu le problème: Merci beaucoup Steve. Tu a été d'une aide précieuse. J'ai étudié la géographie à l'université, pas la programmation, donc c'est assez difficile pour moi. Voici le code final qui fonctionne pour moi.
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()
Je ne comprends pas vraiment les lignes entre "results = cursor.fetchall ()" et les quatre lignes de code suivantes qui impliquent la création de tableaux. Je suis content que vous le fassiez, car je le regarde et il ne s'enfonce toujours pas. Merci beaucoup. Cela aide beaucoup. David