Add vrect with text to plotly express with button

Question:

I have the following code for a vertical rectangle in plotly express:

fig.add_vrect(
    x0 = '2020-04',
    x1 = '2020-09',
    fillcolor="red",
    opacity=0.25
)

I would like to make a button where the user can toggle with rectangle on and off, and when it’s on there’s some text in the middle. I would like them to be off by default.

Asked By: imad97

||

Answers:

You can use dictionaries to create your rectangle shape and rectangle annotation and then use these as arguments for a button. A few details: we use the "relayout" method for buttons because toggling a shape and text annotation means we are only changing the layout, and args and args2 tells the button how to behave when toggled on/off.

Edit: in order to keep another shape (like a vline) on the figure, you can add the vline to both args and args2 of your button so the vline remains when the button is toggled

import plotly.express as px

fig = px.scatter(
    x=['2020-01-30', '2020-04-01', '2020-04-01','2020-09-01'],
    y=[3,2,3,2]
)

fig.add_vline(
    x='2020-02',
    line_dash='dash'
)

vline_shape = [dict(
    type='line',
    x0='2020-02',
    x1='2020-02',
    xref='x',
    y0=0,
    y1=1,
    yref='y domain',
    line= {'dash': 'dash'}
)]

rectangle_shape = [dict(
    type='rect',
    x0='2020-04',
    x1='2020-09',
    xref='x',
    y0=0,
    y1=1,
    yref='y domain',
    fillcolor='red',
    opacity=0.25
)]

rectangle_annotation = [dict(
    showarrow=False,
    x='2020-06-15',
    y=2.5,
    text="Selected Time Period"
)]

fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            buttons=[
                dict(label="Toggle Rectangle",
                     method="relayout",
                     args=[{
                        "shapes": rectangle_shape + vline_shape, 
                        "annotations": rectangle_annotation}],
                     args2=[{
                        "shapes": vline_shape, 
                        "annotations": []}]),
                # dict(label="Untoggle Rectangle",
                #      method="relayout",
                #      args=["shapes", []]),
            ],
        )
    ]
)

fig.show()

enter image description here

Answered By: Derek O