Сюжетно: Как определить цвет маркера на основе значения строки категории для 3D-точечной диаграммы?

#python #colors #plotly #plotly-python

Вопрос:

Я использую 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']
 

Комментарии:

1. Я думаю, что спецификация цвета для маркеров должна представлять собой массив названий цветов или цифр. Почему бы не указать название цвета в соответствии со столбцом данных?

2. Спасибо r-новичкам, могу ли я указать название цвета, используя столбец номера категории, например, используя параметр hue в seaborn? Спасибо

3. Формат-массив или список, поэтому я не думаю, что это возможно. Если возможен формат словаря, есть способ, но проще всего добавить в фрейм данных новый столбец с именем цвета, соответствующим номеру категории.

4. Спасибо вам, начинающие. Я попробую

Ответ №1:

Возможно, я здесь ошибаюсь, но мне кажется, что вы на самом деле просите широко используемую встроенную функцию 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']) , чтобы изменить категорию, с которой вы хотели бы связать свои цвета.

введите описание изображения здесь

Сюжетно.граф_объекты

Если вы хотите использовать 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()
 

Комментарии:

1. Большое вам спасибо, Вестланд. Я ценю, что вы ответили на мой вопрос. Да, если я использую plotly express с color_discrete_map, это работает. Однако, если я использую plotly только с помощью go. Рисунок(), он не работает. Знаете ли вы метод регулярного сюжетного выражения вместо сюжетного выражения? Спасибо

2. @roudan Да. Я просто включил предложение в первоначальный ответ

3. Спасибо, вестланд. да, это сработало. поэтому, основываясь на том, что я понимаю в вашем коде, я должен использовать for loop и add_trace для тех же точек категории. Спасибо.