使用 Matplotlib 跳过 Python 中的某些值

Skipping certain values in Python with Matplotlib

我目前正在使用 Alpha Vantage API 绘制日内股票图表。数据框包含从 4:00 到 20:00 的值。然而,在我的 matplotlib.pyplot 图表中,x 轴还包括从 20:00 到 4:00 一夜之间的值。我不想要这个,因为它扰乱了美学和 Volume 子图。

问:有什么方法可以跳过实际数据框中不存在的 x 轴值(从 20:00 到 04:00 的值)?

As you can see, the Data Frame clearly jumps from 20:00 to 04:00

However in the Matplotlib chart, the x-Axis contains the values from 20:00 to 4:00, messing with the chart

到目前为止的代码。我相信到目前为止一切都是正确的:

import pandas as pd
import matplotlib.pyplot as plt
from alpha_vantage.timeseries import TimeSeries
import time
import datetime as dt
from datetime import timedelta as td 
from dateutil.relativedelta import relativedelta

#Accessing and Preparing API
ts = TimeSeries(key=api_key, output_format='pandas')

ticker_input = "TSLA"
interval_input = "15min"
df, meta_data = ts.get_intraday(symbol = ticker_input, interval = interval_input, outputsize = 'full')
slice_date = 16*4*5
df = df[0:slice_date]
df = df.iloc[::-1]
df["100ma"] = df["4. close"].rolling(window = 50, min_periods = 0).mean()
df["Close"] = df["4. close"]
df["Date"] = df.index

#Plotting all as 2 different subplots
ax1 = plt.subplot2grid((7,1), (0,0), rowspan = 5, colspan = 1)
ax1.plot(df["Date"], df['Close'])
ax1.plot(df["Date"], df["100ma"], linewidth = 0.5)
plt.xticks(rotation=45)
ax2 = plt.subplot2grid((6,1), (5,0), rowspan = 2, colspan = 2, sharex = ax1)
ax2.bar(df["Date"], df["5. volume"])
ax2.axes.xaxis.set_visible(False)
plt.tight_layout()
plt.show()

如果有人能提供帮助就太好了。我仍然是一个完全的初学者,Python 2 周前才开始。

我们从同一个地方获取数据,虽然数据获取方式不同。在以 15 个单位提取后,我通过排除晚上 8 点之后和下午 4 点之前的数据创建了一个图表。我在理解您的跳过会打开暂停的情况下创建了代码。一旦设置了 NaN,您希望它跳过的内容就会被跳过。

import datetime
import pandas as pd
import numpy as np
import pandas_datareader.data as web
import mplfinance as mpf
# import matplotlib.pyplot as plt

with open('./alpha_vantage_api_key.txt') as f:
    api_key = f.read()

now_ = datetime.datetime.today()

start = datetime.datetime(2019, 1, 1)
end = datetime.datetime(now_.year, now_.month, now_.day - 1)

symbol = 'TSLA'
df = web.DataReader(symbol, 'av-intraday', start, end, api_key=api_key)

df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
df.index = pd.to_datetime(df.index)
df["100ma"] = df["Close"].rolling(window = 50, min_periods = 0).mean()
df["Date"] = df.index
df_15 = df.asfreq('15min')
df_15 = df_15[(df_15.index.hour >= 4)&(df_15.index.hour <= 20) ]

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,4.5),dpi=144)

#Plotting all as 2 different subplots
ax1 = plt.subplot2grid((7,1), (0,0), rowspan = 5, colspan = 1)
ax1.plot(df_15["Date"], df_15['Close'])
ax1.plot(df_15["Date"], df_15["100ma"], linewidth = 0.5)
plt.xticks(rotation=20)

ax2 = plt.subplot2grid((6,1), (5,0), rowspan = 2, colspan = 2, sharex = ax1)
ax2.bar(df_15["Date"], df_15["Volume"])
ax2.axes.xaxis.set_visible(False)
# plt.tight_layout()
plt.show()

我用 matplotlib.ticker.formatter 修复了它。

我首先创建了一个 class 并使用:

class MyFormatter(Formatter):
    def __init__(self, dates, fmt='%Y-%m-%d %H:%M'):
        self.dates = dates
        self.fmt = fmt

    def __call__(self, x, pos=0):
        'Return the label for time x at position pos'
        ind = int(np.round(x))
    if ind >= len(self.dates) or ind < 0:
        return ''
    return self.dates[ind].strftime(self.fmt)

formatter = MyFormatter(df.index)
ax1 = plt.subplot2grid((7,1), (0,0), rowspan = 5, colspan = 1)
ax1.xaxis.set_major_formatter(formatter)
ax1.plot(np.arange(len(df)), df["Close"])
ax1.plot(np.arange(len(df)), df["100ma"], linewidth = 0.5)
ax1.xticks(rotation=45)
ax1.axis([xmin,xmax,ymin,ymax])
ax2 = plt.subplot2grid((6,1), (5,0), rowspan = 2, colspan = 2, sharex = ax1)
ax2.bar(np.arange(len(df)), df["5. volume"])

plt.show()

这给了我一个比之前更平滑的图表,也是 r-beginner 推荐的图表。

我唯一的问题是如果我放大 x-axis 并没有真正改变。它总是有年、月、日、小时和分钟。显然,当我进一步放大时,我只想要小时和分钟。我还没有弄清楚该怎么做