问题
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