#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 для тех же точек категории. Спасибо.