Plotting data of a mysql database by date

為{幸葍}努か 提交于 2019-12-11 14:22:57

问题


I created a mysql-database to save the humidity, temperature and several other datas with a timestamp. I can plot the data, but the x-axis is not labeled.

I tried to set the label of the ticks, which did not labeled them correctly. It was not possible to see on which date which data was saved. The type of the dates is datetime.datetime()

result = cursor.fetchall()

for r in result:
    dates.append(r[1])
    humidity.append(r[2])
    temperature.append(r[3])
    pm25.append(r[4])
    pm10.append(r[5])


fig, ax = plt.subplots()

for tick in ax.get_xticklabels():
    tick.set_rotation(45)


ax.plot(dates, humidity, color = 'b')
ax.plot(dates, temperature, color = 'r')
ax.plot(dates, pm25, color = 'orange')
ax.plot(dates, pm10, color = 'g')

plt.show()

I want the dates to label the x-axis and if it is possible to mark every new day with a bigger tick.


回答1:


I have not been able to reproduce your problem without an example of your data, but I wrote some code using mine. My database is sqlite3, but that doesn't really matter.

Getting the data

Pandas have a read_sql_query method which you might find useful. I'm using its parse_dates and index_col to read the data straight into a pandas dataframe with a datetime index.

# read_sql_query
with sqlite3.connect(my_db) as con:
    query = "SELECT humidity, ground_temp, ambient_temp, reading_timestamp from Measurements WHERE Measurements.stations_id = 591441"
    to_plot = pd.read_sql_query(sql=query, con=con, parse_dates=['reading_timestamp'], index_col='reading_timestamp')  

If you prefer fetchall() I can achieve the same result like this:

# fetchall
with sqlite3.connect(my_db) as con:
    query = "SELECT humidity, ground_temp, ambient_temp, reading_timestamp from Measurements WHERE Measurements.stations_id = 591441"
    to_plot = con.execute(query).fetchall()
    to_plot = pd.DataFrame(to_plot, columns=['humidity', 'ground_temp', 'ambient_temp', 'reading_timestamp']).set_index('reading_timestamp')

Here is my data:

                           humidity  ground_temp  ambient_temp
reading_timestamp                                             
2019-05-21 14:55:02+00:00     70.66        14.31         16.33
2019-05-22 10:25:02+00:00     42.08        14.56         15.37
2019-05-23 12:25:02+00:00     55.07        15.75         17.49
2019-05-24 03:25:02+00:00     65.10        16.88         21.25
2019-05-27 13:55:02+00:00     57.46        18.50         25.12

Index is datetime:

to_plot.index

DatetimeIndex(['2019-05-21 14:55:02+00:00', '2019-05-22 10:25:02+00:00',
               '2019-05-23 12:25:02+00:00', '2019-05-24 03:25:02+00:00',
               '2019-05-27 13:55:02+00:00'],
              dtype='datetime64[ns, UTC]', name='reading_timestamp', freq=None)

Now I have a range of options how to plot.

1. Plot the whole DataFrame

The easiest and the quickest, but less customizable.

fig, ax = plt.subplots()
plt.plot(to_plot)
for tick in ax.get_xticklabels():
    tick.set_rotation(45)

2. Plot individual Series

More control, assigns labels automatically so I can easily add a legend.

fig, ax = plt.subplots()
ax.plot(to_plot['ambient_temp'], 'orange')
ax.plot(to_plot['ground_temp'], 'red')
ax.plot(to_plot['humidity'], 'blue')
for tick in ax.get_xticklabels():
    tick.set_rotation(45)
ax.legend()

3. Plotting lists should work as well

But I don't see any benefit in this use case. Plotting Series gives the same result with less typing.

# Convert to lists
dates = list(to_plot.index)
ambient_temp = list(to_plot['ambient_temp'])
ground_temp = list(to_plot['ground_temp'])
humidity = list(to_plot['humidity'])
# Plot lists
fig, ax = plt.subplots()
ax.plot(dates, ambient_temp, 'orange', label='ambient_temp')
ax.plot(dates, ground_temp, 'red', label='ground_temp')
ax.plot(dates, humidity, 'blue', label='humidity')
for tick in ax.get_xticklabels():
    tick.set_rotation(45)
ax.legend()

Days in a bigger font

Now to get days to display in a bigger font, I would suggest that you set days as major ticks using matplotlib.dates and then format them the way you want.

fig, ax = plt.subplots()
ax.plot(to_plot['ambient_temp'], 'orange')
ax.plot(to_plot['ground_temp'], 'red')
ax.plot(to_plot['humidity'], 'blue')
for tick in ax.get_xticklabels():
    tick.set_rotation(45)
ax.legend()

import matplotlib.dates as mdates
# mdates detects days
days = mdates.DayLocator()
# format for days
days_fmt = mdates.DateFormatter('%Y-%m-%d')
# days are major ticks
ax.xaxis.set_major_locator(days)
# format major ticks as days
ax.xaxis.set_major_formatter(days_fmt)
# give major ticks on x-axis a large font
ax.tick_params(axis='x', which='major', labelsize=13)



来源:https://stackoverflow.com/questions/56331512/plotting-data-of-a-mysql-database-by-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!