我在破折号中有一个散点图,有一些点击回调。我想点击它时显示一个点的注释。对于已单击的任何点,注释应保持可见。有谁知道这是否可能;我该怎么办呢?我的初步搜索没有产生任何具体的例子或线索。
import json
from textwrap import dedent as d
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import random
userSeq = []
app = dash.Dash(__name__)
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
app.layout = html.Div([
dcc.Graph(
id='basic-interactions',
figure={
'data': [
{
'x': [random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)],
'y': [random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)],
'text': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
#'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers+text',
'marker': {'size': 12},
'textposition': 'bottom'
}
]
}
),
html.Div(className='row', children=[
html.Div([
dcc.Markdown(d("""
**Click Data**
Click on points in the graph.
""")),
html.Pre(id='click-data', style=styles['pre']),
], className='three columns'),
])
])
@app.callback(
Output('click-data', 'children'),
[Input('basic-interactions', 'clickData')])
def display_click_data(clickData):
if clickData != None:
userSeq.append(clickData['points'][0]['x'])
print(userSeq)
return json.dumps(clickData, indent=2)
if __name__ == '__main__':
app.run_server(debug=True)
答案 0 :(得分:0)
也许它有点矫枉过正,但是你可以做的就是:你在破折号回调中重新定义散点图注释的风格。
据我所知,唯一的方法是重新定义Figure
组件的dcc.Graph
。
import json
from textwrap import dedent as d
import dash
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import random
# NOTE: this variable will be shared across users!
userSeq = []
x_coords = [random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)]
y_coords = [random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)]
app = dash.Dash(__name__)
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
app.layout = html.Div([
dcc.Graph(
id='basic-interactions',
figure={
'data': [
{
'x': x_coords,
'y': y_coords,
'text': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
#'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers+text',
'marker': {'size': 12},
'textposition': 'bottom'
}
],
},
),
html.Div(className='row', children=[
html.Div([
dcc.Markdown(d("""
**Click Data**
Click on points in the graph.
""")),
html.Pre(id='click-data', style=styles['pre']),
], className='three columns'),
])
])
@app.callback(
output=Output('click-data', 'children'),
inputs=[Input('basic-interactions', 'clickData')])
def display_click_data(clickData):
if clickData is not None:
point = clickData['points'][0]
userSeq.append({'x': point['x'], 'y': point['y']})
print(userSeq)
return json.dumps(clickData, indent=2)
@app.callback(
Output('basic-interactions', 'figure'),
[Input('basic-interactions', 'clickData')])
def update_annotation_style(clickData):
"""Redefine Figure with an updated style for the scatter plot annotations."""
data = go.Data([
go.Scatter(
x=x_coords,
y=y_coords,
text=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
name='Trace 1',
mode='markers+text',
marker={'size': 12},
textposition='bottom',
)
])
annotations = []
for point in userSeq:
annotation = {
'x': point['x'],
'y': point['y'],
'xref': 'x',
'yref': 'y',
'text': '({}; {})'.format(point['x'], point['y']),
'align': 'center',
'ay': -15,
'opacity': 0,
'bgcolor': 'yellow',
}
annotations.append(annotation)
if clickData is None:
layout = go.Layout(annotations=annotations)
else:
updated_annotations = list(map(lambda ann: {**ann, 'opacity': 1.0}, annotations))
layout = go.Layout(annotations=updated_annotations)
figure = go.Figure(data=data, layout=layout)
return figure
if __name__ == '__main__':
app.run_server(debug=True)
我的实现中存在一个错误:注释显示所有点击的点,除了当前点(因此当你点击两个点时它们会开始显示)。
我认为这个问题是由运行两个破折号回调的顺序引起的:Output('basic-interactions', 'figure')
的那个应该运行第二个。
请注意,您的应用userSeq
会在用户之间共享,因此如果user A
点击散点图中的3个点,user B
点击散点图中的2个点,他们都会看到5个注释。