Formatierung von Datums-Ticks mit ConciseDateFormatter#

Das Finden guter Tick-Werte und die Formatierung der Ticks für eine Achse mit Datumsdaten ist oft eine Herausforderung. ConciseDateFormatter soll die für die Tick-Labels gewählten Zeichenketten verbessern und die in diesen Tick-Labels verwendeten Zeichenketten so weit wie möglich minimieren.

Hinweis

Dieser Formatter ist ein Kandidat, um der Standard-Datum-Tick-Formatter in zukünftigen Versionen von Matplotlib zu werden. Bitte melden Sie alle Probleme oder Verbesserungsvorschläge an das GitHub-Repository oder die Mailingliste.

import datetime

import matplotlib.pyplot as plt
import numpy as np

import matplotlib.dates as mdates

Zuerst, der Standard-Formatter.

base = datetime.datetime(2005, 2, 1)
dates = [base + datetime.timedelta(hours=(2 * i)) for i in range(732)]
N = len(dates)
np.random.seed(19680801)
y = np.cumsum(np.random.randn(N))

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')),
        (np.datetime64('2005-02-03'), np.datetime64('2005-02-15')),
        (np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))]
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
    # rotate_labels...
    for label in ax.get_xticklabels():
        label.set_rotation(40)
        label.set_horizontalalignment('right')
axs[0].set_title('Default Date Formatter')
plt.show()
Default Date Formatter

Der Standard-Datum-Formatter ist ziemlich ausführlich, daher haben wir die Option, ConciseDateFormatter zu verwenden, wie unten gezeigt. Beachten Sie, dass für dieses Beispiel die Labels nicht gedreht werden müssen, wie es beim Standard-Formatter der Fall ist, da die Labels so klein wie möglich sind.

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
for nn, ax in enumerate(axs):
    locator = mdates.AutoDateLocator(minticks=3, maxticks=7)
    formatter = mdates.ConciseDateFormatter(locator)
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(formatter)

    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')

plt.show()
Concise Date Formatter

Wenn alle Aufrufe von Achsen mit Datumsangaben mit diesem Konverter erfolgen sollen, ist es wahrscheinlich am praktischsten, die Einheitenregistrierung zu verwenden, wo Sie importieren

import matplotlib.units as munits

converter = mdates.ConciseDateConverter()
munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter

fig, axs = plt.subplots(3, 1, figsize=(6, 6), layout='constrained')
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')

plt.show()
Concise Date Formatter

Lokalisierung von Datumsformaten#

Datumsformate können lokalisiert werden, wenn die Standardformate nicht erwünscht sind, indem eine von drei Zeichenkettenlisten manipuliert wird.

Die Liste der Formate formatter.formats ist für die normalen Tick-Labels. Es gibt sechs Ebenen: Jahre, Monate, Tage, Stunden, Minuten, Sekunden. formatter.offset_formats ist, wie die "Offset"-Zeichenkette rechts von der Achse formatiert wird. Dies ist normalerweise viel ausführlicher als die Tick-Labels. Schließlich sind formatter.zero_formats die Formate der "Null"-Ticks. Dies sind Tick-Werte, die entweder der erste des Jahres, Monats oder Tages des Monats oder die Stunde, Minute oder Sekunde null sind. Dies sind normalerweise die gleichen wie das Format der Ticks auf der darüber liegenden Ebene. Wenn beispielsweise die Achsenlimits bedeuten, dass die Ticks hauptsächlich Tage sind, beschriften wir den 1. März 2005 einfach mit "Mär". Wenn die Achsenlimits hauptsächlich Stunden sind, beschriften wir den 4. Feb um 00:00 Uhr einfach mit "4. Feb".

Beachten Sie, dass diese Formatlisten auch als optionale Schlüsselwortargumente an ConciseDateFormatter übergeben werden können.

Hier ändern wir die Labels zu "Tag Monat Jahr" anstelle des ISO-Formats "Jahr Monat Tag"

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))

for nn, ax in enumerate(axs):
    locator = mdates.AutoDateLocator()
    formatter = mdates.ConciseDateFormatter(locator)
    formatter.formats = ['%y',  # ticks are mostly years
                         '%b',       # ticks are mostly months
                         '%d',       # ticks are mostly days
                         '%H:%M',    # hrs
                         '%H:%M',    # min
                         '%S.%f', ]  # secs
    # these are mostly just the level above...
    formatter.zero_formats = [''] + formatter.formats[:-1]
    # ...except for ticks that are mostly hours, then it is nice to have
    # month-day:
    formatter.zero_formats[3] = '%d-%b'

    formatter.offset_formats = ['',
                                '%Y',
                                '%b %Y',
                                '%d %b %Y',
                                '%d %b %Y',
                                '%d %b %Y %H:%M', ]
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(formatter)

    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')

plt.show()
Concise Date Formatter

Registrierung eines Konverters mit Lokalisierung#

ConciseDateFormatter hat keine rcParams-Einträge, aber die Lokalisierung kann erreicht werden, indem Schlüsselwortargumente an ConciseDateConverter übergeben und die zu verwendenden Datentypen bei der Einheitenregistrierung registriert werden.

import datetime

formats = ['%y',          # ticks are mostly years
           '%b',     # ticks are mostly months
           '%d',     # ticks are mostly days
           '%H:%M',  # hrs
           '%H:%M',  # min
           '%S.%f', ]  # secs
# these can be the same, except offset by one level....
zero_formats = [''] + formats[:-1]
# ...except for ticks that are mostly hours, then it's nice to have month-day
zero_formats[3] = '%d-%b'
offset_formats = ['',
                  '%Y',
                  '%b %Y',
                  '%d %b %Y',
                  '%d %b %Y',
                  '%d %b %Y %H:%M', ]

converter = mdates.ConciseDateConverter(
    formats=formats, zero_formats=zero_formats, offset_formats=offset_formats)

munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter registered non-default')

plt.show()
Concise Date Formatter registered non-default

Gesamtlaufzeit des Skripts: (0 Minuten 5,625 Sekunden)

Galerie generiert von Sphinx-Gallery