mdates 定位器在我的图表中显示了不存在的时间区间
我正在尝试为股市制作一个streamlit仪表板。我的股票数据是从早上9点到下午4点的。我在x轴上使用了定位器来标记刻度。然而,图表显示了一些不存在的时间段,比如在图上,刻度之间有很大的间隙,并且在下午4点到早上9点之间画了一条直线。我想去掉这个间隙,让图表变得连续。请问我该怎么解决这个问题?我尝试过滤我的数据,但没有成功。
这是我的代码和一些示例输出。
def create_plot(name:str,label:str,title_info:str,data,period_var:str):
fig, ax1 = plt.subplots(figsize=(16,8))
ax1.set_ylabel(name)
plt.xlabel('Datetime')
plt.ylabel(label)
plt.title(title_info)
if period_var in ["1d"]:
date_formatter = DateFormatter('%H:%M')
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.MinuteLocator(interval=30))
elif period_var in ["3d","5d"]:
date_formatter = DateFormatter("%d-%H")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.HourLocator(byhour=range(9,16),interval=2))
elif period_var in ["1mo", "3mo", "6mo"]:
date_formatter = DateFormatter("%Y - %b")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.DayLocator(interval=int(period_var[0])*2))
elif period_var in ["1y", "2y", "5y"]:
date_formatter = DateFormatter("%Y-%b")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=int(period_var[0])))
else:
date_formatter = DateFormatter("%Y")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.YearLocator())
ax1.plot(data.Date, data[name], label=name, marker='o', markersize=1)
plt.xticks(rotation=45)
plt.legend()
plt.grid(True)
plt.tight_layout()
return fig
如果有人能帮我解决这个问题,我会很感激。
我尝试过滤我的数据,即数据["日期"],但没有效果。我想去掉那些在我的数据框中不存在的时间段。
2 个回答
1
一种方法是用原来的索引来重新排列你过滤后的数据表,这样在你不想绘制的时间点就会出现NaN(缺失值)记录。
最小可复现示例(MVCE):
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.random(2_000),
index=pd.date_range('2021-10-03 07:00:00',
periods=2_000, freq='T'),
columns=['value'])
dfs = df.between_time('09:00','15:00')
dfs.reindex(df.index).plot()
输出结果:
与不重新排列索引的情况对比:
dfs.plot()
0
我已经解决了我的问题,忽略了日期时间索引,并设置了新的刻度。下面是我代码的最新版本。如果有人遇到同样的问题,希望这对你们有帮助。
def create_plot(name: str, label: str, title_info: str, data, period_var: str):
fig, ax1 = plt.subplots(figsize=(16, 8), sharex=True)
data.index = pd.to_datetime(data.index)
ax1.set_ylabel(name)
plt.xlabel('Datetime')
plt.ylabel(label)
plt.title(title_info)
if period_var in ["1d"]:
date_formatter = DateFormatter('%H:%M')
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.MinuteLocator(interval=30))
ax1.plot(data.index, data[name], label=name, marker='o', markersize=1)
fill_green(data=data,name=name,ax1=ax1)
elif period_var in ["3d", "5d"]:
date_formatter = DateFormatter("%d-%H")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.HourLocator(byhour=range(9, 16), interval=30))
ax1.plot(range(data.index.size), data[name], label=name, marker='o', markersize=1)
ymin = min(data[name])
ymax = max(data[name])
padding = 0.05 * (ymax - ymin)
ax1.set_ylim(ymin - padding, ymax + padding)
ax1.fill_between(range(data.index.size), data[name], color='green', alpha=0.3)
ticks_date = data.index.indexer_at_time('08:00')
ticks_time = np.arange(data.index.size)[data.index.minute == 0][::2]
ax1.set_xticks(ticks_date)
ax1.set_xticks(ticks_time, minor=True)
labels_date = [maj_tick.strftime('\n%d-%b').replace('\n0', '\n')
for maj_tick in data.index[ticks_date]]
labels_time = [min_tick.strftime('%d %I %p').lstrip('0').lower()
for min_tick in data.index[ticks_time]]
ax1.set_xticklabels(labels_date)
ax1.set_xticklabels(labels_time, minor=True)
elif period_var in ["1mo", "3mo", "6mo"]:
date_formatter = DateFormatter("%Y - %b")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.plot(data.index, data[name], label=name, marker='o', markersize=1)
ax1.xaxis.set_major_locator(mdates.DayLocator(interval=int(period_var[0]) * 2))
fill_green(data=data,name=name,ax1=ax1)
elif period_var in ["1y", "2y", "5y"]:
date_formatter = DateFormatter("%Y-%b")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=int(period_var[0])))
ax1.plot(data.index, data[name], label=name, marker='o', markersize=1)
fill_green(data=data,name=name,ax1=ax1)
else:
date_formatter = DateFormatter("%Y")
ax1.xaxis.set_major_formatter(date_formatter)
ax1.xaxis.set_major_locator(mdates.YearLocator())
ax1.plot(data.index, data[name], label=name, marker='o', markersize=1)
fill_green(data=data,name=name,ax1=ax1)
plt.xticks(rotation=45)
plt.legend()
plt.grid(False)
plt.tight_layout()
return fig