I'm trying to add custom labels for some special x-values on a plot that has datetimes on the x-axis. Here is a sample of the plot:
from matplotlib import pyplot as plt
from matplotlib.dates import AutoDateLocator, ConciseDateFormatter
import numpy as np
x = np.array([1100, 1800, 2900], 'datetime64[ms]')
y = np.array([1.1, -0.9, 0.2])
labels = {k: v for k, v in zip(x, ['A', 'B', 'C'])}
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(x, y)
locator = AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(ConciseDateFormatter(locator))
So far so good.
Now I want to add some ticks at the locations given by x
with labels set to labels
. When I try to use x
as a datetime, I get a slew of errors:
from matplotlib.ticker import FixedLocator, FuncFormatter
ax.xaxis.set_minor_locator(FixedLocator(x))
Traceback (most recent call last):
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 4628, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1103, in get_tightbbox
ticks_to_draw = self._update_ticks()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1053, in _update_ticks
minor_locs = self.get_minorticklocs()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1292, in get_minorticklocs
minor_locs = [
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1294, in <listcomp>
if ~np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()]
File "<__array_function__ internals>", line 180, in isclose
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2375, in isclose
return within_tol(x, y, atol, rtol)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2356, in within_tol
return less_equal(abs(x-y), atol rtol * abs(y))
numpy.core._exceptions._UFuncBinaryResolutionError: ufunc 'subtract' cannot use operands with types dtype('<M8[ms]') and dtype('float64')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/_constrained_layout.py", line 546, in get_pos_and_bbox
tightbbox = ax.get_tightbbox(renderer=renderer, for_layout_only=True)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 4632, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1103, in get_tightbbox
ticks_to_draw = self._update_ticks()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1053, in _update_ticks
minor_locs = self.get_minorticklocs()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1292, in get_minorticklocs
minor_locs = [
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1294, in <listcomp>
if ~np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()]
File "<__array_function__ internals>", line 180, in isclose
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2375, in isclose
return within_tol(x, y, atol, rtol)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2356, in within_tol
return less_equal(abs(x-y), atol rtol * abs(y))
numpy.core._exceptions._UFuncBinaryResolutionError: ufunc 'subtract' cannot use operands with types dtype('<M8[ms]') and dtype('float64')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 4628, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1103, in get_tightbbox
ticks_to_draw = self._update_ticks()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1053, in _update_ticks
minor_locs = self.get_minorticklocs()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1292, in get_minorticklocs
minor_locs = [
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1294, in <listcomp>
if ~np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()]
File "<__array_function__ internals>", line 180, in isclose
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2375, in isclose
return within_tol(x, y, atol, rtol)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2356, in within_tol
return less_equal(abs(x-y), atol rtol * abs(y))
numpy.core._exceptions._UFuncBinaryResolutionError: ufunc 'subtract' cannot use operands with types dtype('<M8[ms]') and dtype('float64')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/backends/backend_qt.py", line 477, in _draw_idle
self.draw()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 436, in draw
self.figure.draw(self.renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/artist.py", line 73, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
return draw(artist, renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/figure.py", line 2828, in draw
self.execute_constrained_layout(renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/figure.py", line 3186, in execute_constrained_layout
return do_constrained_layout(fig, renderer, h_pad, w_pad,
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/_constrained_layout.py", line 110, in do_constrained_layout
make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/_constrained_layout.py", line 315, in make_layout_margins
pos, bbox = get_pos_and_bbox(ax, renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/_constrained_layout.py", line 548, in get_pos_and_bbox
tightbbox = ax.get_tightbbox(renderer=renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 4632, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(renderer)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1103, in get_tightbbox
ticks_to_draw = self._update_ticks()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1053, in _update_ticks
minor_locs = self.get_minorticklocs()
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1292, in get_minorticklocs
minor_locs = [
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/matplotlib/axis.py", line 1294, in <listcomp>
if ~np.isclose(tr_loc, tr_major_locs, atol=tol, rtol=0).any()]
File "<__array_function__ internals>", line 180, in isclose
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2375, in isclose
return within_tol(x, y, atol, rtol)
File "/home/madphysicist/myvenv/lib/python3.8/site-packages/numpy/core/numeric.py", line 2356, in within_tol
return less_equal(abs(x-y), atol rtol * abs(y))
numpy.core._exceptions._UFuncBinaryResolutionError: ufunc 'subtract' cannot use operands with types dtype('<M8[ms]') and dtype('float64')
When I try to use an integer or float representation of x
, the statements run, but nothing shows up on the graph:
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float)))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(int)))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float)))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e3))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e-3))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e6))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e-6))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e9))
ax.xaxis.set_minor_locator(FixedLocator(x.astype(float) * 1e-9))
How do I add date-based ticks as a set of minor ticks to a plot displaying dates on the x-axis?
The end goal is to be able to do something like this:
ax.xaxis.set_minor_locator(FixedLocator(<magic>)))
ax.xaxis.set_minor_formatter(FuncFormatter(lambda x, pos: labels[x]))
ax.tick_params('x', which='minor', rotation=-75)
Useful Resources After the fact