Issue
I am producing a pcolor plot of some variable, seeing how it behaves over different times and heights. There are thousands of data points and if we don't do anything to the x axis, it just numbers them as shown below:
I then proceded adding the following lines of code, which would remap those increments to timestamps (every data point has a time associated to it):
num_ticks = len(Windspeed_height_plot_data)
skip_every= 600 #only displays every 600th timestamp
ax.set_xticks(np.linspace(0, num_ticks , num_ticks +1)[::skip_every] , time_list[::skip_every], fontsize = 16)
The new plot produced looks like this, which is much better:
The question I have now, is how do we make it so that it only displays the time every 4 hours in the HH:00 format, rather than having to manually tell it to display every n-th time.
I tried using the matplotlib date module with the following code:
hours = mdates.HourLocator(interval = 1)
h_fmt = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_locator(hours)
ax.xaxis.set_major_formatter(h_fmt)
fig.autofmt_xdate()
But had no luck.
Here is the code used to generate the plots:
def time_plot(data, title, Vrange = 28, Vmin = 0):
fig, ax = plt.subplots(figsize=(16, 4), dpi = 300)
readings = np.shape(Windspeed_height_plot_data)[1]
#height = readings*30+49 + 60 #this is for the y axis labaels, all is fine
#every_nth = 5 #decluters the y labels #this is for the y axis labaels, all is fine
#ax.set_yticks(np.linspace(0, readings, readings+1)[::every_nth] , np.linspace(49+60, height , readings+1, dtype=int)[::every_nth], fontsize = 16) #this is for the y axis labaels, all is fine
num_ticks = len(Windspeed_height_plot_data)
skip_every= 600 #only displays every 600th timestamp
ax.set_xticks(np.linspace(0, num_ticks , num_ticks +1)[::skip_every] , time_list[::skip_every], fontsize = 16)
h = ax.pcolor(data, vmin = Vmin, vmax = Vrange, cmap = 'rainbow')
plt.title(title, fontsize = 20)
plt.xlabel("Time EST (hh:mm)", fontsize = 20)
plt.ylabel("Height (m)", fontsize=20)
plt.colorbar(h)
ax.xaxis.get_offset_text().set_fontsize(18)
Solution
Assuming that time_list
consists of datetimes and has data at least once a minute, one can iterate over its elements and filter for these occurences:
from datetime import datetime, timedelta
import numpy as np
from matplotlib import pyplot as plt
# generate random data and times
data = np.random.randn(900)
time_list = [datetime.now() + timedelta(minutes=i) for i in range(len(data))]
# define hour increment
delta_hours = 4
# find "delta-hour" indices and times
filtered_indices = []
filtered_times = []
t_next = time_list[0]
for i, t in enumerate(time_list):
if t > t_next and t.minute == 0:
filtered_indices.append(i)
filtered_times.append(t.strftime("%H:%M"))
# jump to shortly before next delta_hour and find next index
t_next = t + timedelta(hours=delta_hours) - timedelta(minutes=2)
# plot
plt.plot(data)
plt.gca().set_xticks(filtered_indices, filtered_times)
plt.show()
Answered By - Christian Karcher
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.