日期刻度定位器和格式化器#

这个例子展示了各种日期定位器和格式化器的使用和效果。

import matplotlib.pyplot as plt
import numpy as np

from matplotlib.dates import (FR, MO, MONTHLY, SA, SU, TH, TU, WE,
                              AutoDateFormatter, AutoDateLocator,
                              ConciseDateFormatter, DateFormatter, DayLocator,
                              HourLocator, MicrosecondLocator, MinuteLocator,
                              MonthLocator, RRuleLocator, SecondLocator,
                              WeekdayLocator, YearLocator, rrulewrapper)
import matplotlib.ticker as ticker


def plot_axis(ax, locator=None, xmax='2002-02-01', fmt=None, formatter=None):
    """Set up common parameters for the Axes in the example."""
    ax.spines[['left', 'right', 'top']].set_visible(False)
    ax.yaxis.set_major_locator(ticker.NullLocator())
    ax.tick_params(which='major', width=1.00, length=5)
    ax.tick_params(which='minor', width=0.75, length=2.5)
    ax.set_xlim(np.datetime64('2000-02-01'), np.datetime64(xmax))
    if locator:
        ax.xaxis.set_major_locator(eval(locator))
        ax.xaxis.set_major_formatter(DateFormatter(fmt))
    else:
        ax.xaxis.set_major_formatter(eval(formatter))
    ax.text(0.0, 0.2, locator or formatter, transform=ax.transAxes,
            fontsize=14, fontname='Monospace', color='tab:blue')

日期定位器#

locators = [
    # locator as str, xmax, fmt
    ('AutoDateLocator(maxticks=8)', '2003-02-01', '%Y-%m'),
    ('YearLocator(month=4)', '2003-02-01', '%Y-%m'),
    ('MonthLocator(bymonth=[4, 8, 12])', '2003-02-01', '%Y-%m'),
    ('DayLocator(interval=180)', '2003-02-01', '%Y-%m-%d'),
    ('WeekdayLocator(byweekday=SU, interval=4)', '2000-07-01', '%a %Y-%m-%d'),
    ('HourLocator(byhour=range(0, 24, 6))', '2000-02-04', '%H h'),
    ('MinuteLocator(interval=15)', '2000-02-01 02:00', '%H:%M'),
    ('SecondLocator(bysecond=(0, 30))', '2000-02-01 00:02', '%H:%M:%S'),
    ('MicrosecondLocator(interval=1000)', '2000-02-01 00:00:00.005', '%S.%f'),
    ('RRuleLocator(rrulewrapper(freq=MONTHLY, \nbyweekday=(MO, TU, WE, TH, FR), '
     'bysetpos=-1))', '2000-07-01', '%Y-%m-%d'),
]

fig, axs = plt.subplots(len(locators), 1, figsize=(8, len(locators) * .8),
                        layout='constrained')
fig.suptitle('Date Locators')
for ax, (locator, xmax, fmt) in zip(axs, locators):
    plot_axis(ax, locator, xmax, fmt)
Traceback (most recent call last):
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/sphinx_gallery/scrapers.py", line 377, in save_figures
    rst = scraper(block, block_vars, gallery_conf)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/doc/sphinxext/util.py", line 16, in matplotlib_reduced_latex_scraper
    return matplotlib_scraper(block, block_vars, gallery_conf, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/sphinx_gallery/scrapers.py", line 173, in matplotlib_scraper
    fig.savefig(image_path, **these_kwargs)
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/figure.py", line 3451, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/backend_bases.py", line 2138, in print_figure
    self.figure.draw(renderer)
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/artist.py", line 94, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/figure.py", line 3212, in draw
    self.get_layout_engine().execute(self)
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/layout_engine.py", line 273, in execute
    return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/_constrained_layout.py", line 116, in do_constrained_layout
    make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/_constrained_layout.py", line 388, in make_layout_margins
    pos, bbox = get_pos_and_bbox(ax, renderer)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/_constrained_layout.py", line 641, in get_pos_and_bbox
    tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/artist.py", line 1402, in _get_tightbbox_for_layout_only
    return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axes/_base.py", line 4502, in get_tightbbox
    ba = martist._get_tightbbox_for_layout_only(axis, renderer)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/artist.py", line 1402, in _get_tightbbox_for_layout_only
    return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axis.py", line 1350, in get_tightbbox
    self._update_label_position(renderer)
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axis.py", line 2391, in _update_label_position
    bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axis.py", line 2184, in _get_tick_boxes_siblings
    tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axis.py", line 1329, in _get_ticklabel_bboxes
    return ([tick.label1.get_window_extent(renderer)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/axis.py", line 1329, in <listcomp>
    return ([tick.label1.get_window_extent(renderer)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/text.py", line 962, in get_window_extent
    bbox, info, descent = self._get_layout(self._renderer)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/text.py", line 382, in _get_layout
    w, h, d = _get_text_metrics_with_cache(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/text.py", line 69, in _get_text_metrics_with_cache
    return _get_text_metrics_with_cache_impl(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/text.py", line 77, in _get_text_metrics_with_cache_impl
    return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 220, in get_text_width_height_descent
    font.set_text(s, 0.0, flags=get_hinting_flag())
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/_text_helpers.py", line 23, in warn_on_missing_glyph
    _api.warn_external(
  File "/Users/cw/baidu/code/fin_tool/github/matplotlib/venv/lib/python3.11/site-packages/matplotlib/_api/__init__.py", line 391, in warn_external
    warnings.warn(message, category, **kwargs)
UserWarning: Glyph 26085 (\N{CJK UNIFIED IDEOGRAPH-65E5}) missing from font(s) DejaVu Sans.

日期格式化器#

formatters = [
    'AutoDateFormatter(ax.xaxis.get_major_locator())',
    'ConciseDateFormatter(ax.xaxis.get_major_locator())',
    'DateFormatter("%b %Y")',
]

fig, axs = plt.subplots(len(formatters), 1, figsize=(8, len(formatters) * .8),
                        layout='constrained')
fig.suptitle('Date Formatters')
for ax, fmt in zip(axs, formatters):
    plot_axis(ax, formatter=fmt)

由 Sphinx-Gallery 生成的图库