Pergunta

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

Atualmente estou usando esse comando para traçar altos e baixos financeiros usando Matplotlib . Ele funciona muito bem, mas como faço para remover os espaços em branco no eixo X deixado por dias sem dados de mercado, tais como fins de semana e feriados?

Eu tenho listas de datas, altos, baixos, fecha e abre. Não consigo encontrar qualquer exemplos de criação de um gráfico com um eixo x que datas dos espetáculos, mas não impõe uma escala constante.

Foi útil?

Solução

Eu acho que você precisa "artificialmente sintetizar" a forma exata do enredo você quer usando xticks para definir os rótulos de escala para as cordas que representam as datas (de colocar claro que os carrapatos em intervalos equidistantes, embora as datas que você está representando não estão equidistantes) e, em seguida, usando um plot simples.

Outras dicas

Há um exemplo de como fazer isso no site da Matplotlib:

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

I usará tipicamente NumPy de NaN (não um número), para os valores inválido ou não presente. Eles são representados por Matplotlib como lacunas na trama e NumPy faz parte de 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()

Uma das características anunciadas de scikits.timeseries é "Criar parcelas de séries temporais com rótulos dos eixos de forma inteligente espaçados ".

Você pode ver alguns exemplos de parcelas aqui . No primeiro exemplo (mostrado abaixo) a freqüência 'negócio' é usado para os dados, o que automaticamente feriados e fins de semana exclui e similares. Também máscaras falta pontos de dados, o que você vê como lacunas neste enredo, em vez de linearmente interpolando-los.

text alt

Até resposta data (2018) com Matplotlib 2.1.2, Python 2.7.12

A função equidate_ax alças tudo que você precisa para uma data x eixo simples com espaçamento equidistante dos pontos de dados. Realizado com ticker.FuncFormatter baseado em neste exemplo .

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)

Comparação do padrão método e eixo-x equidistante plotagem

Eu corri para este problema novamente e foi capaz de criar uma função decente para lidar com esta questão, especialmente em relação datetimes intraday. Crédito para @Primer para esta resposta.

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()   

funcionalidade scikits.timeseries tem sido amplamente mudou-se para pandas, então agora você pode resample uma trama de dados de modo a incluir apenas os valores nos dias de semana.

>>>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, em seguida, para traçar a trama de dados como normal

s.resample('B', label='right', closed='right').last().plot()
plt.show()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top