Domanda

ax.plot_date((dates, dates), (highs, lows), '-')

Attualmente sto usando questo comando per tracciare alti e bassi finanziari che utilizzano Matplotlib . E le grandi opere, ma come faccio a rimuovere gli spazi vuoti nella asse x data da giorni senza dati di mercato, come i fine settimana e festivi?

Ho liste di date, alti, bassi, si chiude e si apre. Non riesco a trovare alcun esempio di creazione di un grafico con un asse x che mostrano le date, ma non far rispettare una scala costante.

È stato utile?

Soluzione

Credo che hai bisogno di "artificialmente sintetizzare" la forma esatta del lotto desiderato utilizzando xticks per impostare le etichette delle tacche alle stringhe che rappresentano le date (ovviamente mettendo le zecche a intervalli equidistanti, anche se le date che stai rappresentano non sono equidistanti) e poi con un plot pianura.

Altri suggerimenti

C'è un esempio di come fare questo sul sito Matplotlib:

https://matplotlib.org/gallery/ticks_and_spines/date_index_formatter.html

Io di solito utilizzare NumPy s ' NaN (non un numero) per i valori che sono non valida o non presente. Sono rappresentati da Matplotlib come lacune nella trama e NumPy fa parte della pylab / Matplotlib.

>>> import pylab
>>> xs = pylab.arange(10.) + 733632. # valid date range
>>> ys = [1,2,3,2,pylab.nan,2,3,2,5,2.4] # some data (one undefined)
>>> pylab.plot_date(xs, ys, ydate=False, linestyle='-', marker='')
[<matplotlib.lines.Line2D instance at 0x0378D418>]
>>> pylab.show()

Una delle caratteristiche pubblicizzate di scikits.timeseries è "Creare grafici di serie temporali con le etichette degli assi in modo intelligente distanziati ".

È possibile vedere alcuni esempi di trame qui . Nel primo esempio (illustrato di seguito) la frequenza 'business' è usato per i dati, che esclude automaticamente le vacanze e weekend e simili. E 'anche maschere mancanti punti di dati, che si vede come le lacune in questa trama, piuttosto che l'interpolazione lineare.

alt text

Fino ad oggi la risposta (2018) con Matplotlib 2.1.2, Python 2.7.12

La equidate_ax funzione gestisce tutto il necessario per una data semplice asse x con una spaziatura equidistante di punti di dati. Realizzato con ticker.FuncFormatter sulla base di questo esempio .

from __future__ import division
from matplotlib import pyplot as plt
from matplotlib.ticker import FuncFormatter
import numpy as np
import datetime


def equidate_ax(fig, ax, dates, fmt="%Y-%m-%d", label="Date"):
    """
    Sets all relevant parameters for an equidistant date-x-axis.
    Tick Locators are not affected (set automatically)

    Args:
        fig: pyplot.figure instance
        ax: pyplot.axis instance (target axis)
        dates: iterable of datetime.date or datetime.datetime instances
        fmt: Display format of dates
        label: x-axis label
    Returns:
        None

    """    
    N = len(dates)
    def format_date(index, pos):
        index = np.clip(int(index + 0.5), 0, N - 1)
        return dates[index].strftime(fmt)
    ax.xaxis.set_major_formatter(FuncFormatter(format_date))
    ax.set_xlabel(label)
    fig.autofmt_xdate()


#
# Some test data (with python dates)
#
dates = [datetime.datetime(year, month, day) for year, month, day in [
    (2018,2,1), (2018,2,2), (2018,2,5), (2018,2,6), (2018,2,7), (2018,2,28)
]]
y = np.arange(6)


# Create plots. Left plot is default with a gap
fig, [ax1, ax2] = plt.subplots(1, 2)
ax1.plot(dates, y, 'o-')
ax1.set_title("Default")
ax1.set_xlabel("Date")


# Right plot will show equidistant series
# x-axis must be the indices of your dates-list
x = np.arange(len(dates))
ax2.plot(x, y, 'o-')
ax2.set_title("Equidistant Placement")
equidate_ax(fig, ax2, dates)

Confronto di metodo di plottaggio di default ed equidistanti asse x

Mi sono imbattuto in questo problema ancora una volta ed è stato in grado di creare una funzione decente per gestire questo problema, soprattutto per quanto riguarda datetimes intraday. Credito al @Primer questa risposta.

def plot_ts(ts, step=5, figsize=(10,7), title=''):
    """
    plot timeseries ignoring date gaps

    Params
    ------
    ts : pd.DataFrame or pd.Series
    step : int, display interval for ticks
    figsize : tuple, figure size
    title: str
    """

    fig, ax = plt.subplots(figsize=figsize)
    ax.plot(range(ts.dropna().shape[0]), ts.dropna())
    ax.set_title(title)
    ax.set_xticks(np.arange(len(ts.dropna())))
    ax.set_xticklabels(ts.dropna().index.tolist());

    # tick visibility, can be slow for 200,000+ ticks 
    xticklabels = ax.get_xticklabels() # generate list once to speed up function
    for i, label in enumerate(xticklabels):
        if not i%step==0:
            label.set_visible(False)  
    fig.autofmt_xdate()   

funzionalità scikits.timeseries è stato in gran parte trasferito a panda, in modo da ora è possibile ricampionare un dataframe per includere solo i valori nei giorni feriali.

>>>import pandas as pd
>>>import matplotlib.pyplot as plt

>>>s = pd.Series(list(range(10)), pd.date_range('2015-09-01','2015-09-10'))
>>>s

2015-09-01    0
2015-09-02    1
2015-09-03    2
2015-09-04    3
2015-09-05    4
2015-09-06    5
2015-09-07    6
2015-09-08    7
2015-09-09    8
2015-09-10    9

>>> s.resample('B', label='right', closed='right').last()
2015-09-01    0
2015-09-02    1
2015-09-03    2
2015-09-04    3
2015-09-07    6
2015-09-08    7
2015-09-09    8
2015-09-10    9

e poi per tracciare la dataframe come normale

s.resample('B', label='right', closed='right').last().plot()
plt.show()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top