
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "gallery/ticks/date_index_formatter.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. meta::
        :keywords: codex

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_gallery_ticks_date_index_formatter.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_gallery_ticks_date_index_formatter.py:


=====================================
Custom tick formatter for time series
=====================================

.. redirect-from:: /gallery/text_labels_and_annotations/date_index_formatter
.. redirect-from:: /gallery/ticks/date_index_formatter2

When plotting daily data, e.g., financial time series, one often wants
to leave out days on which there is no data, for instance weekends, so that
the data are plotted at regular intervals without extra spaces for the days
with no data.
The example shows how to use an 'index formatter' to achieve the desired plot.

.. GENERATED FROM PYTHON SOURCE LINES 15-64

.. code-block:: Python


    import matplotlib.pyplot as plt
    import numpy as np

    import matplotlib.cbook as cbook
    from matplotlib.dates import DateFormatter, DayLocator
    import matplotlib.lines as ml
    from matplotlib.ticker import Formatter

    # Load a structured numpy array from yahoo csv data with fields date, open, high,
    # low, close, volume, adj_close from the mpl-data/sample_data directory. The
    # record array stores the date as an np.datetime64 with a day unit ('D') in
    # the date column (``r['date']``).
    r = cbook.get_sample_data('goog.npz')['price_data']
    r = r[:9]  # get the first 9 days

    fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6, 6), layout='constrained')
    fig.get_layout_engine().set(hspace=0.15)

    # First we'll do it the default way, with gaps on weekends
    ax1.plot(r["date"], r["adj_close"], 'o-')

    # Highlight gaps in daily data
    gaps = np.flatnonzero(np.diff(r["date"]) > np.timedelta64(1, 'D'))
    for gap in r[['date', 'adj_close']][np.stack((gaps, gaps + 1)).T]:
        ax1.plot(gap['date'], gap['adj_close'], 'w--', lw=2)
    ax1.legend(handles=[ml.Line2D([], [], ls='--', label='Gaps in daily data')])

    ax1.set_title("Plot y at x Coordinates")
    ax1.xaxis.set_major_locator(DayLocator())
    ax1.xaxis.set_major_formatter(DateFormatter('%a'))


    # Next we'll write a custom index formatter. Below we will plot
    # the data against an index that goes from 0, 1,  ... len(data).  Instead of
    # formatting the tick marks as integers, we format as times.
    def format_date(x, _):
        try:
            # convert datetime64 to datetime, and use datetime's strftime:
            return r["date"][round(x)].item().strftime('%a')
        except IndexError:
            pass

    # Create an index plot (x defaults to range(len(y)) if omitted)
    ax2.plot(r["adj_close"], 'o-')

    ax2.set_title("Plot y at Index Coordinates Using Custom Formatter")
    ax2.xaxis.set_major_formatter(format_date)  # internally creates FuncFormatter




.. image-sg:: /gallery/ticks/images/sphx_glr_date_index_formatter_001.png
   :alt: Plot y at x Coordinates, Plot y at Index Coordinates Using Custom Formatter
   :srcset: /gallery/ticks/images/sphx_glr_date_index_formatter_001.png, /gallery/ticks/images/sphx_glr_date_index_formatter_001_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 65-67

Instead of passing a function into `.Axis.set_major_formatter` you can use
any other callable, e.g. an instance of a class that implements __call__:

.. GENERATED FROM PYTHON SOURCE LINES 67-85

.. code-block:: Python



    class MyFormatter(Formatter):
        def __init__(self, dates, fmt='%a'):
            self.dates = dates
            self.fmt = fmt

        def __call__(self, x, pos=0):
            """Return the label for time x at position pos."""
            try:
                return self.dates[round(x)].item().strftime(self.fmt)
            except IndexError:
                pass


    ax2.xaxis.set_major_formatter(MyFormatter(r["date"], '%a'))

    plt.show()








.. _sphx_glr_download_gallery_ticks_date_index_formatter.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: date_index_formatter.ipynb <date_index_formatter.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: date_index_formatter.py <date_index_formatter.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: date_index_formatter.zip <date_index_formatter.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
