Plotly: como definir cores em uma figura usando plotly.graph_objects e plotly.express?
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
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'))