情节:如何在两条垂直线之间设置填充颜色? [英] Plotly: How to set a fill color between two vertical lines?

查看:137
本文介绍了情节:如何在两条垂直线之间设置填充颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用matplotlib,我们可以平凡地"使用如示例所示,使用fill_between()填充两条垂直线之间的区域:

Using matplotlib, we can "trivially" fill the area between two vertical lines using fill_between() as in the example:

https://matplotlib.org/3.2.1/gallery/lines_bars_and_markers/fill_between_demo.html#selectively-marking-horizo​​ntal-regions-across-the-hole-axes

使用matplotlib,我可以满足需要:

Using matplotlib, I can make what I need:

我们有两个信号,我正在计算皮尔逊和斯皮尔曼的滚动/运动相关性.当相关性低于-0.5或高于0.5时,我想给句点加阴影(蓝色表示皮尔逊(Pearson),橙色表示Spearman(橙色)).在所有情节中,我还将周末都设为灰色.

We have two signals, and I''m computing the rolling/moving Pearson's and Spearman's correlation. When the correlations go either below -0.5 or above 0.5, I want to shade the period (blue for Pearson's and orange for Spearman's). I also darken the weekends in gray in all plots.

但是,我很难使用Plotly完成相同的任务.知道如何在两条水平线之间进行操作也将很有帮助.

However, I'm finding a hard time to accomplish the same using Plotly. And it will also be helpful to know how to do it between two horizontal lines.

请注意,我正在使用Plotly和Dash来加速多个图的可视化.用户要求更动态类型的事物".但是,尽管我需要给他们初步的结果,但我不是GUI的人,不能花时间在上面.

Note that I'm using Plotly and Dash to speed up the visualization of several plots. Users asked for a more "dynamic type of thing." However, I'm not a GUI guy and cannot spend time on this, although I need to feed them with initial results.

顺便说一句,我过去曾尝试过Bokeh,但由于某种原因我不记得了,我放弃了.由于我可以从Python或R(这是我的主要开发工具)中使用它,因此显示出良好的外观.

BTW, I tried Bokeh in the past, and I gave up for some reason I cannot remember. Plotly looks good since I can use either from Python or R, which are my main development tools.

谢谢

卡洛斯

推荐答案

您尚未提供数据示例,因此我将使用综合时间序列向您展示如何添加多个已定义的形状使用自定义功能bgLevel

You haven't provided a data sample so I'm going to use a synthetical time-series to show you how you can add a number of shapes with defined start and stop dates for several different categories using a custom function bgLevel

两条垂直线之间有一个填充,很快就会变成一个矩形.使用fig.add_shape可以轻松地将矩形添加为形状.下面的示例将向您展示如何查找特定标准所指定时间段的开始日期和结束日期.就您而言,这些条件是变量的值是高于还是低于某个特定水平.

Two vertical lines with a fill between them very quickly turns into a rectangle. And rectangles can easily be added as shapes using fig.add_shape. The example below will show you how to find start and stop dates for periods given by a certain critera. In your case these criteria are whether or not the value of a variable is higher or lower than a certain level.

fig.add_trace()中使用形状代替轨迹,可以使用layer='below'定义有关绘制图层的位置.并且可以使用 line=dict(color="rgba(0,0,0,0))轻松隐藏形状轮廓.

Using shapes instead of traces with fig.add_trace() will let you define the position with regards to plot layers using layer='below'. And the shapes outlines can easily be hidden using line=dict(color="rgba(0,0,0,0)).

图1:带有随机数据的时间序列图:

Plot 1: Time series figure with random data:

图2:A > 100时,背景设置为不透明的灰色:

Plot 2: Background is set to an opaque grey when A > 100 :

图2:D < 60

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import datetime

pd.set_option('display.max_rows', None)

# data sample
nperiods = 200
np.random.seed(123)
df = pd.DataFrame(np.random.randint(-10, 12, size=(nperiods, 4)),
                  columns=list('ABCD'))
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),periods=nperiods).tolist()
df['dates'] = datelist 
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)
df.iloc[0] = 0
df = df.cumsum().reset_index()

# function to set background color for a
# specified variable and a specified level



# plotly setup
fig = px.line(df, x='dates', y=df.columns[1:])
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')

def bgLevels(fig, variable, level, mode, fillcolor, layer):
    """
    Set a specified color as background for given
    levels of a specified variable using a shape.
    
    Keyword arguments:
    ==================
    fig -- plotly figure
    variable -- column name in a pandas dataframe
    level -- int or float
    mode -- set threshold above or below
    fillcolor -- any color type that plotly can handle
    layer -- position of shape in plotly fiugre, like "below"
    
    """
    
    if mode == 'above':
        m = df[variable].gt(level)
    
    if mode == 'below':
        m = df[variable].lt(level)
        
    df1 = df[m].groupby((~m).cumsum())['dates'].agg(['first','last'])

    for index, row in df1.iterrows():
        #print(row['first'], row['last'])
        fig.add_shape(type="rect",
                        xref="x",
                        yref="paper",
                        x0=row['first'],
                        y0=0,
                        x1=row['last'],
                        y1=1,
                        line=dict(color="rgba(0,0,0,0)",width=3,),
                        fillcolor=fillcolor,
                        layer=layer) 
    return(fig)

fig = bgLevels(fig = fig, variable = 'A', level = 100, mode = 'above',
               fillcolor = 'rgba(100,100,100,0.2)', layer = 'below')

fig = bgLevels(fig = fig, variable = 'D', level = -60, mode = 'below',
               fillcolor = 'rgba(255,0,0,0.2)', layer = 'below')

fig.show()

这篇关于情节:如何在两条垂直线之间设置填充颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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