【问题标题】:Plotly: How to add vertical lines at specified points?Plotly:如何在指定点添加垂直线?
【发布时间】:2020-05-25 20:39:04
【问题描述】:

我有一个时间序列的数据框图以及我想在其上绘制垂直线的数值列表。该图是使用 cufflinks 包创建的交互式图。这是 1000 个时间值的三个时间序列的示例,我想在 500 和 800 处绘制垂直线。我使用“axvlinee”的尝试是基于我在类似帖子中看到的建议:

import numpy as np
import pandas as pd
import cufflinks

np.random.seed(123)
X = np.random.randn(1000,3)  
df=pd.DataFrame(X, columns=['a','b','c'])
fig=df.iplot(asFigure=True,xTitle='time',yTitle='values',title='Time Series Plot')
fig.axvline([500,800], linewidth=5,color="black", linestyle="--")
fig.show()

错误消息指出“Figure”对象没有“axvline”属性。

我不确定此消息是由于我对基本绘图缺乏了解还是源于使用 igraph 的限制。

【问题讨论】:

标签: python pandas plotly cufflinks


【解决方案1】:

答案:

要在现有的绘图图中添加一条线,只需使用:

fig.add_shape(type='line',...)

详情:

我收集 this 是您在使用 matplotlib 后看到的帖子。正如 cmets 中所述,axvline 与情节无关。这仅用作您如何使用 matplotlib 完成它的示例。使用 plotly,我要么选择fig.add_shape(go.layout.Shape(type="line")。但在您自己尝试之前,请注意 cufflinks 已被弃用。我真的很喜欢袖扣,但现在有更好的选择来构建快速和详细的图表。如果你想坚持类似于iplot 的单行,我建议使用plotly.express。在您的情况下,唯一的障碍是将您的数据集从宽格式更改为 plotly.express 首选的长格式。下面的 sn-p 正是为了产生以下情节:

代码:

import numpy as np
import pandas as pd
import plotly.express as px
from plotly.offline import iplot
#
np.random.seed(123)
X = np.random.randn(1000,3)  
df=pd.DataFrame(X, columns=['a','b','c'])
df['id'] = df.index
df = pd.melt(df, id_vars='id', value_vars=df.columns[:-1])

# plotly line figure
fig = px.line(df, x='id', y='value', color='variable')

# lines to add, specified by x-position
lines = {'a':500,'c':700,'a':900,'b':950}

# add lines using absolute references
for k in lines.keys():
    #print(k)
    fig.add_shape(type='line',
                yref="y",
                xref="x",
                x0=lines[k],
                y0=df['value'].min()*1.2,
                x1=lines[k],
                y1=df['value'].max()*1.2,
                line=dict(color='black', width=3))
    fig.add_annotation(
                x=lines[k],
                y=1.06,
                yref='paper',
                showarrow=False,
                text=k)
fig.show()

【讨论】:

    【解决方案2】:

    不确定这是否是您想要的,添加两个 scatter 似乎可行:

    np.random.seed(123)
    X = np.random.randn(1000,3)  
    df=pd.DataFrame(X, columns=['a','b','c'])
    fig = df.iplot(asFigure=True,xTitle='time',yTitle='values',title='Time Series Plot')
    
    fig.add_scatter(x=[500]*100, y=np.linspace(-4,4,100), name='lower')
    fig.add_scatter(x=[800]*100, y=np.linspace(-4,4,100), name='upper')
    
    fig.show()
    

    输出:

    【讨论】:

    • 谢谢这是一个非常好的方法,特别是对于我在这里所说的之外的最终目的,当每条垂直线将与特定系列相关联时,无论是“a”,“b” ,或“c”。例如,我是否可以将 t=500 处的垂直散点图着色为与时间序列“a”的颜色相同,并将 t=800 处的垂直散点图着色为与时间序列“c”相同?