Search code examples
pythonplotlyplotly-dashdashboard

Dash / Plotly draw vrect in graph or change drawn rectangle's height


I'm currently building a time series labeling tool in Dash for which I'm utilizing the plotly inbuild drawrect function in the figure like this:

fig.update_layout(dragmode='drawrect', newshape={
        "drawdirection": "vertical",
        "layer": "below",
        "fillcolor": "green",
        "opacity": 0.25,
        "line": {
            "width": 0
        }
    })

this is perfect with one flaw, the drawn rectangles are only as high as the current zoom and if you zoom out it doesn't fill the whole screen vertically anymore.
I've seen that plotly has the ability to draw vrects which are exaclty what I want but I don't see how can draw them with the mouse. Is there a way I can specify the height or a way to change the height to be infinite as soon as someone draws a rect?


Solution

  • EDIT:

    To generate an infinitely high rectangle upon drawing, you can trigger a callback when drawing a regular rectangle, capture its X-coordinates, delete the layout to remove that rectangle, then draw a vrect that will have the same x-coordinates but will be infinitely high. Here is an example:

    app.layout = html.Div([
        dcc.Graph(
            id="sensor-graph",
            config={
                'modeBarButtonsToAdd': [
                    "drawrect",
                    "eraseshape"
                ]
            },
        ),
    ])
    
    @app.callback(
        [
            Output('sensor-graph', 'figure')
        ],
        Input("sensor-graph", "relayoutData"),
        [State('sensor-graph', 'figure')],
        prevent_initial_call=True
    )
    def on_new_annotation(relayout_data, fig):
        figu = go.Figure(fig)
        # Check if the changed layout in the graph is a drawn shape
        if fig is not None and "shapes" in relayout_data:
            # Remove the original rectangle
            figu.layout = {}
            # Add an infinitely high rectangle, using the original rectangle's x-coords
            figu.add_vrect(x0=relayout_data["shapes"][0]["x0"], x1=relayout_data["shapes"][0]["x1"])
        return [figu]
    

    Original answer: After drawing a rectangle, you can click on it's actual perimeter and it's vertices become drag-able. This way, when you zoom out, you can resize the rectangle's height.

    Here is an example of changing it's height using the drag functionality: enter image description here

    enter image description here

    enter image description here