Plotly:如何使用日期时间索引在中心绘制一条线的范围? [英] Plotly: How to plot a range with a line in the center using a datetime index?

查看:51
本文介绍了Plotly:如何使用日期时间索引在中心绘制一条线的范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想绘制一条围绕它的范围的线,就像这张照片一样:

我发布了一个原始问题,但没有指定索引是日期时间索引.我以为这不重要,但我错了.

有一个答案用数字索引覆盖它:

完整代码:

# 导入导入 plotly.graph_objs as go导入 plotly.express 作为 px将熊猫导入为 pd将 numpy 导入为 np# Pandas 数据帧中的样本数据np.random.seed(1)df=pd.DataFrame(dict(A=np.random.uniform(low=-1, high=2, size=25).tolist(),B=np.random.uniform(low=-4, high=3, size=25).tolist(),C=np.random.uniform(low=-1, high=3, size=25).tolist(),))df = df.cumsum()# 将日期范围设置为索引df['dates'] = pd.date_range('2020', freq='D', period=len(df))df.set_index('dates', inplace=True)# ---# 将颜色定义为列表颜色 = px.colors.qualitative.Plotly# 将绘图十六进制颜色转换为 rgba 以启用透明度调整def hex_rgba(十六进制,透明度):col_hex = hex.lstrip('#')col_rgb = list(int(col_hex[i:i+2], 16) for i in (0, 2, 4))col_rgb.extend([透明度])areacol = 元组(col_rgb)返回区域rgba = [hex_rgba(c,transparent=0.2) for c in colour]colCycle = ['rgba'+str(elem) for elem in rgba]# 如果线条比颜色多,请确保颜色循环运行def next_col(cols):为真:对于 col 中的 col:产量色谱柱line_color=next_col(cols=colCycle)# 情节图fig = go.Figure()# 为每个系列和标准偏差添加线条和阴影区域对于 i, col in enumerate(df):new_col = 下一个(line_color)x = df.indexy1 = df[col]y1_upper = [(y + np.std(df[col])) for y in df[col]]y1_lower = [(y - np.std(df[col])) 用于 df[col]] 中的 yy1_lower = y1_lower[::-1]# 标准差区域fig.add_traces(go.Scatter(#x+x[::-1],x=x.append(x[::-1]),y=y1_upper+y1_lower,填充='tozerox',填充颜​​色=new_col,line=dict(color='rgba(255,255,255,0)'),showlegend=假,名称=列))# 线迹fig.add_traces(go.Scatter(x=df.index,y=y1,line=dict(color=new_col, width=2.5),模式='线',名称=列))fig.update_layout(xaxis=dict(range=[df.index[1],df.index[-1]]))图.show()

I would like to plot a line with a range around it, like on this photo:

I posted an original question, but didn't specify the index being a datetime index. I thought it wouldn't be important, but I was wrong.

There is an answer that covers it with a numerical index:

Plotly: How to make a figure with multiple lines and shaded area for standard deviations?

and documentation here:

https://plotly.com/python/continuous-error-bars/

but the issue of datetime index is not covered.

Here is some test data:

timestamp      price   min  mean   max  
1596267946298  100.0   100  100.5  101
1596267946299  101.0   100  100.5  101
1596267946300  102.0   98   99.5   102
1596267948301  99.0    98   99.5   102
1596267948302  98.0    98   99.5   102
1596267949303  99.0    98   995.   102

where I'd like the band to cover from min to max and the mean to be drawn in the center.

another option is to take the code from the first answer of the question posted above (Plotly: How to make a figure with multiple lines and shaded area for standard deviations?) and change the data generation to:

index = pd.date_range('1/1/2000', periods=25, freq='T')
df = pd.DataFrame(dict(A=np.random.uniform(low=-1, high=2, size=25).tolist(),
                       B=np.random.uniform(low=-4, high=3, size=25).tolist(),
                       C=np.random.uniform(low=-1, high=3, size=25).tolist()),
                  index=index)

this will work the same way but create a datetime index.

解决方案

Compared to the setup in the linked question, what causes trouble is the fact that x+x[::-1] doesn't work very well with a datetime index. But if you set x=df.index in:

# add line and shaded area for each series and standards deviation
for i, col in enumerate(df):
    new_col = next(line_color)
    # x = list(df.index.values+1)
    x = df.index

And then replace x+x[::-1] with x=x.append(x[::-1]):

# standard deviation area
fig.add_traces(go.Scatter(
                            #x+x[::-1],
                            x=x.append(x[::-1]),

Then things should work out perfectly well.

Plot:

Complete code:

# imports
import plotly.graph_objs as go
import plotly.express as px
import pandas as pd
import numpy as np

# sample data in a pandas dataframe
np.random.seed(1)
df=pd.DataFrame(dict(A=np.random.uniform(low=-1, high=2, size=25).tolist(),
                    B=np.random.uniform(low=-4, high=3, size=25).tolist(),
                    C=np.random.uniform(low=-1, high=3, size=25).tolist(),
                    ))
df = df.cumsum()

# set daterange as index
df['dates'] = pd.date_range('2020', freq='D', periods=len(df))
df.set_index('dates', inplace=True)

# ---

# define colors as a list 
colors = px.colors.qualitative.Plotly

# convert plotly hex colors to rgba to enable transparency adjustments
def hex_rgba(hex, transparency):
    col_hex = hex.lstrip('#')
    col_rgb = list(int(col_hex[i:i+2], 16) for i in (0, 2, 4))
    col_rgb.extend([transparency])
    areacol = tuple(col_rgb)
    return areacol

rgba = [hex_rgba(c, transparency=0.2) for c in colors]
colCycle = ['rgba'+str(elem) for elem in rgba]

# Make sure the colors run in cycles if there are more lines than colors
def next_col(cols):
    while True:
        for col in cols:
            yield col
line_color=next_col(cols=colCycle)

# plotly  figure
fig = go.Figure()

# add line and shaded area for each series and standards deviation
for i, col in enumerate(df):
    new_col = next(line_color)
    x = df.index
    y1 = df[col]
    y1_upper = [(y + np.std(df[col])) for y in df[col]]
    y1_lower = [(y - np.std(df[col])) for y in df[col]]
    y1_lower = y1_lower[::-1]

    # standard deviation area
    fig.add_traces(go.Scatter(
                                #x+x[::-1],
                                x=x.append(x[::-1]),
                                y=y1_upper+y1_lower,
                                fill='tozerox',
                                fillcolor=new_col,
                                line=dict(color='rgba(255,255,255,0)'),
                                showlegend=False,
                                name=col))

    # line trace
    fig.add_traces(go.Scatter(x=df.index,
                              y=y1,
                              line=dict(color=new_col, width=2.5),
                              mode='lines',
                              name=col)
                                )
fig.update_layout(xaxis=dict(range=[df.index[1],df.index[-1]]))
fig.show()

这篇关于Plotly:如何使用日期时间索引在中心绘制一条线的范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆