Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙?
Posted
技术标签:
【中文标题】Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙?【英文标题】:Plotly: How to style a plotly figure so that it doesn't display gaps for missing dates? 【发布时间】:2020-08-04 08:25:18 【问题描述】:我有一个以 15 分钟为间隔的几个月内欧元/日元汇率的图表,因此没有从周五晚上到周日晚上的数据。
这里是部分数据,注意周末索引中的跳过(类型:DatetimeIndex):
以 plotly 的形式绘制此数据会导致缺失日期的差距使用上面的数据框:
import plotly.graph_objs as go
candlesticks = go.Candlestick(x=data.index, open=data['Open'], high=data['High'],
low=data['Low'], close=data['Close'])
fig = go.Figure(layout=cf_layout)
fig.add_trace(trace=candlesticks)
fig.show()
输出:
如您所见,缺失日期的位置存在空白。我在网上找到的一种解决方案是使用以下方法将索引更改为文本:
data.index = data.index.strftime("%d-%m-%Y %H:%M:%S")
并再次绘制它,这确实有效,但有它自己的问题。 x 轴标签看起来很糟糕:
我想生成一个图形,该图形绘制第二个图中没有间隙的图形,但 x 轴的显示方式与第一个图形上的一样。或者至少以更简洁和响应式的格式显示,尽可能接近第一个图表。
提前感谢您的帮助!
【问题讨论】:
【参考方案1】:即使您的数据集中缺少某些日期,绘图也会将您的日期解释为日期值,并在您的时间轴上显示甚至丢失的日期。一种解决方案是获取第一个和最后一个日期,构建完整的时间线,找出原始数据集中缺少哪些日期,并将这些日期包含在:
fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])
这将变成这个数字:
进入这个:
完整代码:
import plotly.graph_objects as go
from datetime import datetime
import pandas as pd
import numpy as np
# sample data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
# remove some dates to build a similar case as in the question
df = df.drop(df.index[75:110])
df = df.drop(df.index[210:250])
df = df.drop(df.index[460:480])
# build complete timepline from start date to end date
dt_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1])
# retrieve the dates that ARE in the original datset
dt_obs = [d.strftime("%Y-%m-%d") for d in pd.to_datetime(df['Date'])]
# define dates with missing values
dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d").tolist() if not d in dt_obs]
# make fiuge
fig = go.Figure(data=[go.Candlestick(x=df['Date'],
open=df['AAPL.Open'], high=df['AAPL.High'],
low=df['AAPL.Low'], close=df['AAPL.Close'])
])
# hide dates with no values
fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])
fig.update_layout(yaxis_title='AAPL Stock')
fig.show()
【讨论】:
在大量数据中使用 rangebreaks(如已接受的答案)导致烛台图加载缓慢。下面的代码非常适合我。fig.update_layout(xaxis = dict(type="category"))
@Prasanna Man Rajbanshi 您对这样做的副作用感到满意吗?
不,它们是什么? @vestland
这行得通!对于每小时索引,需要填写一个额外的键“dvalue”,其中 dvalue = 60 * 60 * 1000 表示 60min * 60sec/min * 1000msec/sec。更新行变为 fig.update_xaxes(rangebreaks=[dict(values=dt_breaks, dvalue=dvalue)])。参考这里community.plotly.com/t/…
@KevinZhu 不错的补充!【参考方案2】:
以防万一这里有人想消除非交易时间和周末的差距,
如下图,使用rangebreaks
就是这样做的方法。
fig = go.Figure(data=[go.Candlestick(x=df['date'], open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'])])
fig.update_xaxes(
rangeslider_visible=True,
rangebreaks=[
# NOTE: Below values are bound (not single values), ie. hide x to y
dict(bounds=["sat", "mon"]), # hide weekends, eg. hide sat to before mon
dict(bounds=[16, 9.5], pattern="hour"), # hide hours outside of 9.30am-4pm
# dict(values=["2020-12-25", "2021-01-01"]) # hide holidays (Christmas and New Year's, etc)
]
)
fig.update_layout(
title='Stock Analysis',
yaxis_title=f'symbol Stock'
)
fig.show()
这里是Plotly's doc。
【讨论】:
非常感谢! 这个更适合esp。当涉及到已知假期和市场时间的股票价格时。 @ron 当然!只要您错过的日期仅限于已知假期。【参考方案3】:感谢您提供的惊人样本!适用于每日数据,但日内/5 分钟数据范围突破仅在图表上留下一天
# build complete timepline
dt_all = pd.date_range(start=df.index[0],end=df.index[-1], freq="5T")
# retrieve the dates that ARE in the original datset
dt_obs = [d.strftime("%Y-%m-%d %H:%M:%S") for d in pd.to_datetime(df.index, format="%Y-%m-%d %H:%M:%S")]
# define dates with missing values
dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d %H:%M:%S").tolist() if not d in dt_obs]
【讨论】:
以上是关于Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙?的主要内容,如果未能解决你的问题,请参考以下文章