كيفية تخطي التواريخ الفارغة (عطلات نهاية الأسبوع) في الرسم البياني matplotlib python مالي؟

StackOverflow https://stackoverflow.com/questions/1273472

سؤال

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

أنا حاليا باستخدام هذا الأمر لرسم الارتفاعات المالية والاداءات باستخدام matplotlib.. وبعد إنه يعمل بشكل رائع، ولكن كيف يمكنني إزالة المساحات الفارغة في المحور X الذي تركت منذ أيام دون بيانات السوق، مثل عطلات نهاية الأسبوع والأعياد؟

لدي قوائم بالتواريخ والارواف والأقصاد والإغلاق والفتح. لا يمكنني العثور على أي أمثلة على إنشاء رسم بياني مع محور X الذي يظهر التواريخ ولكن لا يفرض مقياس ثابت.

هل كانت مفيدة؟

المحلول

أعتقد أنك بحاجة إلى "توليف مصطنع" الشكل الدقيق للمصورة التي تريدها باستخدام xticks لتعيين ملصقات التجزئة على الأوتار التي تمثل التواريخ (بالطبع وضع القراد على فترات متساوية على الرغم من أن التواريخ التي تمثلها ليست متساوية) ثم باستخدام سهل plot.

نصائح أخرى

هناك مثال على كيفية القيام بذلك على موقع Matplotlib:

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

سأستمر عادة numpy.نان (وليس عددا) للقيم غير الصحيحة أو غير موجودة. يمثلونها matplotlib حيث أن الفجوات في المؤامرة والحنمة هي جزء من 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()

واحدة من الميزات المعلن عنها scikits.timeseries. "إنشاء مؤامرات سلسلة الوقت مع تسميات المحور متباعدة بذكاء".

يمكنك أن ترى بعض الأمثلة هنا. وبعد في المثال الأول (الموضح أدناه) يستخدم تردد "الأعمال" للبيانات، مما يستبعد تلقائيا العطل وعطلات نهاية الأسبوع وما شابه ذلك. كما أنه أقنع نقاط البيانات المفقودة، والتي تراها ثغرات في هذه المؤامرة، بدلا من الاستراءة الخطي لهم.

alt text

إجابة محدثة (2018) مع Matplotlib 2.1.2، بيثون 2.7.12

الوظيفة equidate_ax يعالج كل ما تحتاجه لتاريخ X-Axis بسيطة مع تباعد متساوي نقاط نقاط البيانات. أدركت مع ticker.FuncFormatter مرتكز على هذا المثال.

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)

Comparison of default plotting method and equidistant x-axis

لقد هربت هذه المشكلة مرة أخرى وتمكنت من إنشاء وظيفة لائقة للتعامل مع هذه المشكلة، خاصة فيما يتعلق بتأثيرات داخلية. الائتمان إلى primer. لهذه الإجابة.

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

تم نقل وظيفة Scikits.TimeSeries إلى الباندا إلى حد كبير، حتى تتمكن الآن من إعادة تشكيل إطارا بيانات لا تتضمن فقط القيم في أيام الأسبوع.

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

ثم قم بمصنع الإطار Data

s.resample('B', label='right', closed='right').last().plot()
plt.show()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top