如何根据下拉列表更新所选标记的颜色?
我有多个集群,群集中的每个数据点都有一个特殊的组。我试图根据选定值(组)从下拉列表中突出显示所选的数据点(带有黄色)。
代码:
import pandas as pd
import numpy as np
def generate_random_cluster(name, size, loc_x, loc_y, groups=['A','B','C'], p=None):
return pd.DataFrame({
'name': name,
'x': np.random.normal(loc=loc_x, size=size),
'y': np.random.normal(loc=loc_y, size=size),
'group': np.random.choice(['A','B','C'], size=size, p=p)
})
groups = ['A','B','C']
cluster_1 = generate_random_cluster(name='cluster_1', size=15, loc_x=3, loc_y=2, groups=groups, p=[0.7, 0.2, 0.1])
cluster_2 = generate_random_cluster(name='cluster_2', size=35, loc_x=9, loc_y=5, groups=groups, p=[0.2, 0.7, 0.1])
cluster_3 = generate_random_cluster(name='cluster_3', size=20, loc_x=6, loc_y=8, groups=groups, p=[0.1, 0.2, 0.7])
data = pd.concat([cluster_1, cluster_2, cluster_3]).reset_index(drop=True)
data.head()
返回这样的数据
名称 | x | y | 组 |
---|---|---|---|
cluster_1 | 3.198048 | 0.385736 | b |
cluster_1 | 1.784080 | 2.608631 | 的 |
cluster_1 | 一个 | 文档 | a |
是 | 这 | 示例数据 | 生成 |
: | 4.160103 | 2.119545 | 框架 |
从 我以为我只需要使用update_layout
这样的方法:
import plotly.graph_objects as go
cluster_colors = {'cluster_1': 'green', 'cluster_2': 'red', 'cluster_3': 'blue'}
layout = go.Layout(
xaxis = go.layout.XAxis(
showticklabels=False),
yaxis = go.layout.YAxis(
showticklabels=False
)
)
fig = go.Figure(layout=layout)
for cluster_ix, (cluster, df) in enumerate(data.groupby('name')):
customdata = df['group']
fig.add_scatter(
x=df['x'],
y=df['y'],
name=cluster,
mode='markers',
customdata=customdata,
hovertemplate="<br>".join([
"X: %{x}",
"Y: %{y}",
"Group: %{customdata}"
]),
marker_color=[cluster_colors[cluster] for _ in range(len(df))],
)
def highlight_group(group):
result = []
for tracer_ix, tracer in enumerate(fig["data"]):
colors = ["yellow" if datapoint_group == group else cluster_colors[fig["data"][tracer_ix]["name"]] for datapoint_group in fig["data"][tracer_ix]["customdata"]]
result.append(colors)
return result
fig.update_layout(
updatemenus=[
{
"buttons": [
{
"label": group,
"method": "update",
"args": [
{"marker": {"color": highlight_group(group)}}
],
}
for group in groups
]
}
],
margin={"l": 0, "r": 0, "t": 25, "b": 0},
height=700
)
fig.show()
这会生成这样的图:
但是当我从下拉列表中更改值时,每个标记都会变黑:
如何正确突出选定的标记?
I have multiple clusters and each datapoint in the cluster has a special group. I am trying to highlight selected data points (with yellow color) in the plotly scatter plot based on selected value (group) from a dropdown list.
Here is a code to generate sample data:
import pandas as pd
import numpy as np
def generate_random_cluster(name, size, loc_x, loc_y, groups=['A','B','C'], p=None):
return pd.DataFrame({
'name': name,
'x': np.random.normal(loc=loc_x, size=size),
'y': np.random.normal(loc=loc_y, size=size),
'group': np.random.choice(['A','B','C'], size=size, p=p)
})
groups = ['A','B','C']
cluster_1 = generate_random_cluster(name='cluster_1', size=15, loc_x=3, loc_y=2, groups=groups, p=[0.7, 0.2, 0.1])
cluster_2 = generate_random_cluster(name='cluster_2', size=35, loc_x=9, loc_y=5, groups=groups, p=[0.2, 0.7, 0.1])
cluster_3 = generate_random_cluster(name='cluster_3', size=20, loc_x=6, loc_y=8, groups=groups, p=[0.1, 0.2, 0.7])
data = pd.concat([cluster_1, cluster_2, cluster_3]).reset_index(drop=True)
data.head()
Which returns dataframe like this:
name | x | y | group |
---|---|---|---|
cluster_1 | 3.198048 | 0.385736 | B |
cluster_1 | 1.784080 | 2.608631 | A |
cluster_1 | 4.160103 | 2.119545 | A |
cluster_1 | 2.522486 | 1.994962 | B |
cluster_1 | 4.073054 | 1.204167 | A |
I am quite new to plotly, but based from documentation I thought I just need to use update_layout
method like this:
import plotly.graph_objects as go
cluster_colors = {'cluster_1': 'green', 'cluster_2': 'red', 'cluster_3': 'blue'}
layout = go.Layout(
xaxis = go.layout.XAxis(
showticklabels=False),
yaxis = go.layout.YAxis(
showticklabels=False
)
)
fig = go.Figure(layout=layout)
for cluster_ix, (cluster, df) in enumerate(data.groupby('name')):
customdata = df['group']
fig.add_scatter(
x=df['x'],
y=df['y'],
name=cluster,
mode='markers',
customdata=customdata,
hovertemplate="<br>".join([
"X: %{x}",
"Y: %{y}",
"Group: %{customdata}"
]),
marker_color=[cluster_colors[cluster] for _ in range(len(df))],
)
def highlight_group(group):
result = []
for tracer_ix, tracer in enumerate(fig["data"]):
colors = ["yellow" if datapoint_group == group else cluster_colors[fig["data"][tracer_ix]["name"]] for datapoint_group in fig["data"][tracer_ix]["customdata"]]
result.append(colors)
return result
fig.update_layout(
updatemenus=[
{
"buttons": [
{
"label": group,
"method": "update",
"args": [
{"marker": {"color": highlight_group(group)}}
],
}
for group in groups
]
}
],
margin={"l": 0, "r": 0, "t": 25, "b": 0},
height=700
)
fig.show()
This generates plot like this:
But when I change the value from the dropdown list, every marker turns black:
How to correctly highlight selected markers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基于 @jmmease的答案在这里情节论坛,我相信您可以重组标记字典:
这是结果:
这完成了您在原始问题中所要求的内容,但是从设计角度来看,您可能需要添加另一个下拉列表选项,所以您可以选择不选择组 - 否则,一旦选择了一个组,就无法将数字返回其原始状态。
由于您的代码非常强大,因此您可以通过
groups+[“ none”]
来创建按钮而不是组(因此我不修改groups
),您标签none
:然后,结果看起来像这样:

下一部分超出了您原始问题的范围,但是传说中可能会有一些潜在的混乱,因为当您创建图形时,每个群集的名称(因此如图所示的标记颜色)在传说中)链接到群集而不是标记颜色 - 这意味着,当您选择某个特定组以彩色“黄色”时,您将拥有一个群集组,其中一些标记为黄色,而其他标记则具有其原始标记颜色,我相信Plotly将必须任意选择颜色为传说 - 可能是组中第一个标记的颜色。
例如,一旦我们从下拉列表中选择
组B
,cluster 3
主要是蓝色标记,如您在创建图时所定义的那样,但是也有来自黄色标记的混合物B组,这导致传奇条目为黄色。对于cluster 2
,存在相同的问题,该问题主要是红色标记,但包含一些B组黄色标记。如果我想到解决方案,我将更新答案。Based on @jmmease's answer here in the plotly forums, I believe you can restructure the markers dictionary:
Here is the result:
This accomplishes what you asked in your original question, but from a design perspective, you might want to add another dropdown option so that you can select no groups – otherwise, once you select a group, you cannot return the figure to its original state.
Since your code is pretty robust, you can iterate through
groups+["None"]
to create the buttons instead of groups (so that I don't modifygroups
), you will have another dropdown option with the labelNone
:Then the result looks like this:

This next part is beyond the scope of your original question, but there may be some potential confusion in the legend because when you create the figure, the name of each cluster (and therefore the marker color as indicated in the legend) is linked to the cluster instead of the marker color – this means that when you select a certain group to color "yellow", you'll have a cluster group where some markers are colored yellow, and other markers have their original color, and I believe plotly will have to choose a color arbitrarily for the legend – probably the color of the first marker within a group.
For example, once we select
Group B
from the dropdown,cluster 3
is mostly blue markers as you defined when creating the figure, but there is also a mixture of yellow markers from Group B, and this causes the legend entry to be colored yellow. The same issue exists forcluster 2
which is mostly red markers but contains some Group B yellow markers. If I think of a solution, I'll update my answer.