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:如何设置绘图图形的样式,使其不显示缺失日期的间隙?的主要内容,如果未能解决你的问题,请参考以下文章

绘图地图不显示几何图形

Plotly 绘图无法在模态中自动缩放

如何调整UITextField文字内容位置,使其不贴边框显示

Plotly:样式化辅助 x 轴

可视化神器Plotly绘制3D图

绘图纸格式不统一