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?
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: