Formattazione dei segni di spunta della data utilizzando ConciseDateFormatter #

Trovare buoni valori di tick e formattare i tick per un asse che contiene dati di data è spesso una sfida. ConciseDateFormatterha lo scopo di migliorare le stringhe scelte per le etichette di spunta e di ridurre al minimo le stringhe utilizzate in quelle etichette di spunta il più possibile.

Nota

Questo formattatore è candidato a diventare il formattatore di tick della data predefinito nelle versioni future di Matplotlib. Si prega di segnalare eventuali problemi o suggerimenti per il miglioramento al repository github o alla mailing list.

import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np

Innanzitutto, il formattatore predefinito.

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, constrained_layout=True, 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()
Formattatore di data predefinito

Il formattatore di data predefinito è piuttosto prolisso, quindi abbiamo la possibilità di utilizzare ConciseDateFormatter, come mostrato di seguito. Si noti che per questo esempio le etichette non devono essere ruotate come avviene per il formattatore predefinito perché le etichette sono le più piccole possibile.

fig, axs = plt.subplots(3, 1, constrained_layout=True, 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()
Formattatore di data conciso

Se tutte le chiamate agli assi che hanno date devono essere effettuate utilizzando questo convertitore, è probabilmente più conveniente utilizzare il registro delle unità in cui si effettuano le importazioni:

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), constrained_layout=True)
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')

plt.show()
Formattatore di data conciso

Localizzazione dei formati di data #

I formati delle date possono essere localizzati se i formati predefiniti non sono desiderabili manipolando uno dei tre elenchi di stringhe.

L' formatter.formatselenco dei formati è per le normali etichette tick, Ci sono sei livelli: anni, mesi, giorni, ore, minuti, secondi. Ecco formatter.offset_formatscome viene formattata la stringa "offset" a destra dell'asse. Questo di solito è molto più prolisso delle etichette di spunta. Infine, formatter.zero_formatsci sono i formati dei tick che sono "zero". Questi sono valori di tick che sono il primo dell'anno, del mese o del giorno del mese oppure l'ora, il minuto o il secondo zero. Di solito sono uguali al formato dei tick di un livello superiore. Ad esempio, se i limiti dell'asse indicano che i tick sono per lo più giorni, etichettiamo il 1 marzo 2005 semplicemente con un "Mar". Se i limiti dell'asse sono per lo più ore, etichettiamo Feb 4 00:00 semplicemente come "Feb-4".

Si noti che questi elenchi di formati possono anche essere passati ConciseDateFormatter come argomenti di parole chiave opzionali.

Qui modifichiamo le etichette in "giorno mese anno", invece dell'ISO "anno mese giorno":

fig, axs = plt.subplots(3, 1, constrained_layout=True, 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()
Formattatore di data conciso

Registrazione di un convertitore con localizzazione #

ConciseDateFormatternon ha voci rcParams, ma la localizzazione può essere eseguita passando argomenti di parole chiave ConciseDateConvertere registrando i tipi di dati che utilizzerai con il registro delle unità:

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 its 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, constrained_layout=True, 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 registrato non predefinito

Tempo di esecuzione totale dello script: (0 minuti 3,859 secondi)

Galleria generata da Sphinx-Gallery