-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathplotlyDash_delete_shapes_by_name.py
140 lines (127 loc) · 3.45 KB
/
plotlyDash_delete_shapes_by_name.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from dash import Dash, dcc, html, Input, Output, State
import dash_bootstrap_components as dbc
from dash.exceptions import PreventUpdate
import plotly.graph_objects as go
import numpy as np
# prepare trace data
data = go.Scatter(
x=[1, 10],
y=[1, 10],
mode='markers',
marker={
'size': 8,
'symbol': 'circle-open',
},
)
# create figure
fig = go.Figure(data=data)
# update layout
fig.update_layout(
template='plotly_dark',
plot_bgcolor='rgba(0, 0, 0, 0)',
paper_bgcolor='rgba(0, 0, 0, 0)',
width=700,
height=500,
margin={
'l': 0,
'r': 0,
't': 20,
'b': 100,
}
)
# add some shapes
for i in range(1, 6):
fig.add_shape(
{
'type': 'rect',
'x0': np.random.randint(1, 5), 'x1': np.random.randint(6, 11),
'y0': np.random.randint(1, 5), 'y1': np.random.randint(6, 11),
},
editable=True,
name=f'shape_{i}',
line={
'color': ['red', 'yellow', 'blue', 'pink'][np.random.randint(0, 4)],
'width': 2,
'dash': 'solid'
},
)
# Build App
app = Dash(
__name__,
external_stylesheets=[dbc.themes.SLATE],
meta_tags=[
{
'name': 'viewport',
'content': 'width=device-width, initial-scale=1.0'
}
]
)
# app layout
app.layout = dbc.Container(
[
dbc.Row(
dbc.Col(
dcc.Graph(
id='graph',
figure=fig,
config={
'scrollZoom': True,
'displayModeBar': False,
}
),
width={'size': 5, 'offset': 0}
), justify='around'
),
dbc.Row(
[
dbc.Col(html.H5('Click button to delete shapes')),
dbc.Col(html.H5('Enter name of shape to delete')),
dbc.Col(html.H5('Available shapes'))
]
),
dbc.Row(
[
dbc.Col(
html.Button(
'Delete',
id='delete'
),
),
dbc.Col(
dcc.Input(
id='box',
type='text',
value='shape_x',
className='input'
),
),
dbc.Col(
html.Div(
id='available',
children=', '.join([f'shape_{i}' for i in range(1, 6)])
)
),
], justify='around'
)
], fluid=True
)
@app.callback(
Output('graph', 'figure'),
Output('available', 'children'),
Input('delete', 'n_clicks'),
State('graph', 'figure'),
State('box', 'value'),
)
def get_click(click, current_figure, shape_to_delete):
if not click:
raise PreventUpdate
else:
# get existing shapes
shapes = current_figure['layout'].get('shapes')
# delete shape, aka keep only the shapes which are not to be deleted
shapes[:] = [shape for shape in shapes if shape.get('name') != shape_to_delete]
# update figure layout
current_figure['layout'].update(shapes=shapes)
return current_figure, ', '.join([shape.get('name') for shape in shapes])
if __name__ == '__main__':
app.run(debug=True, port=8053)