Plotly: como definir cores em uma figura usando plotly.graph_objects e plotly.express?

Aug 17 2020

Existem muitas perguntas e respostas que tocam neste tópico de uma forma ou de outra. Com esta contribuição, gostaria de mostrar claramente por que uma abordagem fácil como marker = {'color' : 'red'}funcionará para plotly.graph_objects (go), mas color='red'não funcionará, plotly.express (px)embora a cor seja um atributo de ambos px.Linee px.Scatter. E eu gostaria de demonstrar por que é incrível que não funcione.


Então, se pxé suposto ser a maneira mais fácil de fazer uma figura gráfica , então por que algo aparentemente tão óbvio quanto color='red'retornar o erro

ValueError: O valor de 'color' não é o nome de uma coluna em 'data_frame'.

Deixe-me demonstrar aplicando um conjunto de dados gapminder e mostrar um gráfico de dispersão de Life expectancyversus GDP per capitapara todos (pelo menos a maioria ) países em todo o mundo a partir de 2007. Uma configuração básica como a abaixo produzirá o seguinte gráfico

Figura 1, plotagem usando go:

A cor é definida por um ciclo denominado plotly, mas é aqui especificada usando marker = {'color' : 'red'}

Figura 2, código:

import plotly.graph_objects as go

df = px.data.gapminder()
df=df.query("year==2007")

fig = go.Figure()
fig.add_traces(go.Scatter(x=df['gdpPercap'], y=df["lifeExp"],
                          mode = 'markers',
                          marker = {'color' : 'red'}
                         ))
fig.show()

Então, vamos tentar fazer isso com px, e assumir que color='red'isso resolverá o problema:

Código 2, tentativa de gráfico de dispersão com cor definida usando px:

# imports
import plotly.express as px
import pandas as pd

# dataframe
df = px.data.gapminder()
df=df.query("year==2007")

# plotly express scatter plot
px.scatter(df, x="gdpPercap", y="lifeExp",
           color = 'red',
          )

Resultado:

ValueError: O valor de 'color' não é o nome de uma coluna em 'data_frame'. Esperado um de ['country', 'continente', 'year', 'lifeExp', 'pop', 'gdpPercap', 'iso_alpha', 'iso_num'] mas recebido: vermelho

Então, o que está acontecendo aqui?

Respostas

7 vestland Aug 18 2020 at 00:22

Primeiro, se uma explicação das diferenças mais amplas entre goe pxfor necessária, dê uma olhada aqui e aqui . E se absolutamente nenhuma explicação for necessária, você encontrará um trecho de código completo no final da resposta que revelará muitos dos poderes com cores em plotly.express


Parte 1: A Essência:

Pode não parecer assim no início, mas há muito boas razões para que color='red'não funciona como você poderia esperar usando px. Mas antes de tudo, se tudo o que você gostaria de fazer é definir manualmente uma cor específica para todos os marcadores, você pode fazer isso usando .update_traces(marker=dict(color='red'))graças ao método de encadeamento de pítons . Mas, primeiro, vamos dar uma olhada nas configurações para surdos:

1.1 Padrões totalmente expressos

Figura 1, gráfico de dispersão padrão de px usando px.Scatter

Código 1, gráfico de dispersão padrão de px usando px.Scatter

# imports
import plotly.express as px
import pandas as pd

# dataframe
df = px.data.gapminder()
df=df.query("year==2007")

# plotly express scatter plot
px.scatter(df, x="gdpPercap", y="lifeExp")

Aqui, como já mencionado na pergunta, a cor é definida como a primeira cor na sequência de plotagem padrão disponível por meio de px.colors.qualitative.Plotly:

['#636EFA', # the plotly blue you can see above
 '#EF553B',
 '#00CC96',
 '#AB63FA',
 '#FFA15A',
 '#19D3F3',
 '#FF6692',
 '#B6E880',
 '#FF97FF',
 '#FECB52']

E isso parece muito bom. Mas e se você quiser mudar as coisas e até adicionar mais informações ao mesmo tempo?

1.2: Como substituir os padrões e fazer exatamente o que quiser com cores px:

Como já mencionamos px.scatter, o coloratributo não assume uma cor como redargumento. Em vez disso, você pode, por exemplo, usar color='continent'para distinguir facilmente entre diferentes variáveis ​​em um conjunto de dados. Mas há muito mais cores em px:


A combinação dos seis métodos a seguir permitirá que você faça exatamente o que gostaria com as cores usando o plotly express. Lembre-se de que você nem precisa escolher . Você pode usar um , alguns ou todos os métodos abaixo ao mesmo tempo. E uma abordagem útil em particular se revelará um combinatino de 1e 3. Mas vamos chegar a isso em breve. Isso é o que você precisa saber:

1. Altere a sequência de cores usada por px com:

color_discrete_sequence=px.colors.qualitative.Alphabet

2. Atribua cores diferentes a variáveis ​​diferentes com o color argumento

color = 'continent'

3. personalizar uma ou mais cores variáveis ​​com

color_discrete_map={"Asia": 'red'}

4. Agrupe facilmente um subconjunto maior de suas variáveis ​​usando compreensão de dicionário ecolor_discrete_map

subset = {"Asia", "Africa", "Oceania"}
group_color = {i: 'red' for i in subset}

5. Defina a opacidade usando rgba()códigos de cores.

color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}

6. Substitua todas as configurações com:

.update_traces(marker=dict(color='red'))

Parte 2: Os detalhes e os enredos

O fragmento a seguir produzirá o gráfico abaixo, que mostra a expectativa de vida em todos os continentes para vários níveis de PIB. O tamanho dos marcadores representa diferentes níveis de populações para tornar as coisas mais interessantes desde o início.

Lote 2:

Código 2:

import plotly.express as px
import pandas as pd

# dataframe, input
df = px.data.gapminder()
df=df.query("year==2007")

px.scatter(df, x="gdpPercap", y="lifeExp",
           color = 'continent',
           size='pop',
          )

Para ilustrar a flexibilidade dos métodos acima, vamos primeiro apenas alterar a sequência de cores . Como nós, para começar, mostramos apenas uma categoria e uma cor, você terá que esperar pelas etapas subsequentes para ver os efeitos reais. Mas aqui está o mesmo gráfico agora com a color_discrete_sequence=px.colors.qualitative.Alphabetetapa 1:

1. Altere a sequência de cores usada por px com

color_discrete_sequence=px.colors.qualitative.Alphabet

Agora, vamos aplicar as cores da Alphabetsequência de cores aos diferentes continentes:

2. Atribua cores diferentes a variáveis ​​diferentes com o color argumento

color = 'continent'

Se você, como eu, acha que esta sequência de cores em particular é agradável aos olhos, mas talvez um pouco indistinguível, pode atribuir uma cor de sua escolha a um ou mais continentes desta forma:

3. personalizar uma ou mais cores variáveis ​​com

color_discrete_map={"Asia": 'red'}

E isso é incrível: agora você pode alterar a sequência e escolher qualquer cor que desejar para variáveis ​​particularmente interessantes. Mas o método acima pode ficar um pouco tedioso se você quiser atribuir uma cor específica a um subconjunto maior. Então, veja como você pode fazer isso também com uma compreensão de dicionário :

4. Atribua cores a um grupo usando uma compreensão de dicionário ecolor_discrete_map

# imports
import plotly.express as px
import pandas as pd

# dataframe
df = px.data.gapminder()
df=df.query("year==2007")

subset = {"Asia", "Europe", "Oceania"}
group_color = {i: 'red' for i in subset}

# plotly express scatter plot
px.scatter(df, x="gdpPercap", y="lifeExp",
           size='pop',
           color='continent',
           color_discrete_sequence=px.colors.qualitative.Alphabet,
           color_discrete_map=group_color
          )

5. Defina a opacidade usando rgba()códigos de cores.

Agora vamos dar um passo para trás. Se você acha que redcombina bem com a Ásia, mas talvez seja um pouco forte demais, você pode ajustar a opacidade usando uma rgbacor como 'rgba(255,0,0,0.4)'esta:

Código completo para o último lote:

import plotly.express as px
import pandas as pd

# dataframe, input
df = px.data.gapminder()
df=df.query("year==2007")

px.scatter(df, x="gdpPercap", y="lifeExp",
           color_discrete_sequence=px.colors.qualitative.Alphabet,
           color = 'continent',
           size='pop',
           color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
          )

E se você acha que estamos ficando um pouco complicados agora, você pode substituir todas as configurações como esta novamente:

6. Substitua todas as configurações com:

.update_traces(marker=dict(color='red'))

E isso nos leva de volta ao ponto de partida. Espero que você ache isso útil!

Snippet de código completo com todas as opções disponíveis:

# imports
import plotly.express as px
import pandas as pd

# dataframe
df = px.data.gapminder()
df=df.query("year==2007")

subset = {"Asia", "Europe", "Oceania"}
group_color = {i: 'red' for i in subset}

# plotly express scatter plot
px.scatter(df, x="gdpPercap", y="lifeExp",
           size='pop',
           color='continent',
           color_discrete_sequence=px.colors.qualitative.Alphabet,
           #color_discrete_map=group_color
           color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
          )#.update_traces(marker=dict(color='red'))