Plotly:如何根据 3d 散点图的类别字符串值定义标记颜色?

Plotly: How to define marker color based on category string value for a 3d scatter plot?

我正在使用 plotly.graph_object 绘制 3D 散点图。我想根据类别字符串值定义标记颜色。类别值为 A2、A3、A4。如何修改下面的代码?谢谢

这是我所做的:


import plotly.graph_objects as go

x=df_merged_pc['PC1']
y=df_merged_pc['PC2']
z=df_merged_pc['PC3']

color=df_merged_pc['AREA']

fig=go.Figure(data=[go.Scatter3d(x=x,y=y,z=z,mode='markers',
                                 marker=dict(size=12,
                                             color=df_merged_pc['AREA'],
                                             colorscale ='Viridis'))])
fig.show()

我得到的错误是:

ValueError: 
    Invalid element(s) received for the 'color' property of scatter3d.marker
        Invalid elements include: ['A3', 'A3', 'A3', 'A3', 'A3', 'A3', 'A3', 'A2', 'A2', 'A2']

我在这里可能是错的,但在我看来,您实际上是在要求 plotly.express 广泛使用的内置功能,您可以在其中为标记数据的子组分配颜色。以数据集px.data.iris为例:

fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
              color='species')

在这里,颜色被分配给不同的物种,你有三个独特的价值['setosa', 'versicolor', 'virginica']:

   sepal_length  sepal_width  petal_length  petal_width species  species_id
0           5.1          3.5           1.4          0.2  setosa           1
1           4.9          3.0           1.4          0.2  setosa           1
2           4.7          3.2           1.3          0.2  setosa           1
3           4.6          3.1           1.5          0.2  setosa           1
4           5.0          3.6           1.4          0.2  setosa           1

可以通过像上面那样更改配色方案来扩展此示例,在这种情况下,您的配色方案可以由字典定义:

colors = {"flower": 'green', 'not a flower': 'rgba(50,50,50,0.6)'} 

或者您可以指定一个离散的颜色序列:

color_discrete_sequence = plotly.colors.sequential.Viridis

您还可以添加一个新列,例如 random.choice(['flower', 'not a flower']) 来更改您希望与颜色关联的类别。

Plotly.graph_objects

如果您想使用 go.Scatter3d 而不是,我会为每个唯一子组构建一个轨迹,并使用 itertools.cycle 设置颜色,如下所示:

colors = cycle(plotly.colors.sequential.Viridis)

fig = go.Figure()
for s in dfi.species.unique():
    df = dfi[dfi.species == s]
    fig.add_trace(go.Scatter3d(x=df['sepal_length'], y = df['sepal_width'], z = df['petal_width'],
                               mode = 'markers',
                               name = s,
                               marker_color = next(colors)))

plotly express的完整代码

import plotly.express as px
import random
df = px.data.iris()
colors = {"flower": 'green', 'not a flower': 'rgba(50,50,50,0.6)'}

df['plant'] = [random.choice(['flower', 'not a flower']) for obs in range(0, len(df))]
fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
                color = 'plant',
                color_discrete_map=colors
                   )
fig.show()

绘图对象的完整代码

import plotly.graph_objects as go
import plotly
from itertools import cycle

dfi = px.data.iris()
colors = cycle(plotly.colors.sequential.Viridis)

fig = go.Figure()
for s in dfi.species.unique():
    df = dfi[dfi.species == s]
    fig.add_trace(go.Scatter3d(x=df['sepal_length'], y = df['sepal_width'], z = df['petal_width'],
                               mode = 'markers',
                               name = s,
                               marker_color = next(colors)))
fig.show()