I would like to show datetimes as ticklabels on the x-axis of a plot via ax.imshow()
. I first tried putting the limits (as datetime
objects) into extent, but it appears that extent only accepts arguments of type <float/int>
. So instead, I would like to create the original plot via ax.imshow(...)
, then make the x-axis invisible, then add in the correct xticks
and xlim
.
I found a similar problem solved using a different approach in this example, but I think my use-case is slightly different; I don't need to convert any time-stamps, but I do know the xlim
of the data (in terms of datetime
objects). Also, I do not think the suggested use of matplotlib.dates.date2num
fits my use-case since some of the data is spaced less than one day apart, but date2num
uses days as a base-unit.
I am stuck trying to make this work using my alternate approach; a simple mini-example is below.
import numpy as np
import datetime
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
def f(x, y):
return np.sqrt(np.square(x) + np.square(y))
## SAMPLE DATA
x = np.arange(10) ## elapsed minutes
y = np.square(x) ## arbitrary y-values
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
## DATETIMES FOR ALTERNATE AXIS
lower_dt = datetime.datetime(1999, 1, 1, 0, 0, 0)
# upper_dt = datetime.datetime(2001, 10, 31, 0, 0, 0)
upper_dt = datetime.datetime(1999, 1, 1, x.size-1, 0, 0)
## DO PLOT
fig, ax = plt.subplots()
ax.xaxis.set_visible(False)
# ax.xaxis.tick_top()
ax.imshow(
Z,
origin='lower',
cmap='Oranges',
norm=Normalize(vmin=np.nanmin(Z), vmax=np.nanmax(X)),
extent=(x[0], x[-1], y[0], y[-1]))
## CONVERT XTICKLABELS OF X-AXIS TO DATETIME
mirror_ax = ax.twiny()
# mirror_ax = ax.figure.add_subplot(ax.get_subplotspec(), frameon=False)
mirror_ax.set_xlim([lower_dt, upper_dt])
plt.show()
plt.close(fig)
The obtained plot can be seen here:
I notice that the xticks
are shown at the top instead of the bottom of the plot - this is unwanted behavior; using ax.tick_top
(commented out above) does not change this. Even worse, the x-axis limits are not retained. I realize I could manually change the xticklabels via ax.get_xticks()
and ax.set_xticklabels(...)
, but I would prefer to leave that for date-formatters and date-locators via matplotlib.
How can I use the approach outlined above to create a "mirror/alternate" x-axis of datetime units such that this x-axis is the same size/orientation of the "original/invisible" x-axis of float/integer units?