Plotly:如何使用 plotly.graph_objects 和 plotly.express 定义图形中的颜色?
问题描述
有许多问题和答案以某种方式触及这个主题.通过这个贡献,我想清楚地说明为什么像 marker = {'color' : 'red'}
这样简单的方法适用于 plotly.graph_objects (go)
,但 color='red'
不会用于 plotly.express (px)
尽管颜色是 px.Line
和 的属性>px.Scatter
.而且我想证明为什么它不那么棒.
所以,如果 px
应该是
颜色由名为
代码1,px默认散点图使用px.Scatter
# 导入将 plotly.express 导入为 px将熊猫导入为 pd# 数据框df = px.data.gapminder()df=df.query("year==2007")# plotly 表示散点图px.scatter(df, x="gdpPercap", y="lifeExp")
这里,正如问题中已经提到的,颜色被设置为默认绘图序列中的第一种颜色,可通过 px.colors.qualitative.Plotly
获得:
['#636EFA', # 你可以在上面看到的蓝色'#EF553B','#00CC96','#AB63FA','#FFA15A','#19D3F3','#FF6692','#B6E880','#FF97FF','#FECB52']
这看起来很不错.但是,如果您想同时更改内容甚至添加更多信息怎么办?
1.2:如何覆盖默认值并完全使用 px 颜色执行您想要的操作:
正如我们已经提到的 px.scatter
一样,color
属性不会像 red
这样的颜色作为参数.相反,您可以例如使用 color='continent'
轻松区分数据集中的不同变量.但是 px
中的颜色还有很多:
以下六种方法的组合将让您完全使用 plotly express 来完成您想要的颜色.请记住,您甚至不必选择.您可以同时使用以下方法中的one、some 或all.一种特别有用的方法将显示为 1
和 3
的组合.但我们稍后会谈到这一点.这是你需要知道的:
1. 改变px使用的颜色顺序:
color_discrete_sequence=px.colors.qualitative.Alphabet
2. 使用 color
参数
color = '大陆'
3. 使用
自定义一种或多种可变颜色color_discrete_map={亚洲":'红色'}
4. 使用 dict 理解和 color_discrete_map
subset = {亚洲"、非洲"、大洋洲"}group_color = {i: 'red' for i in subset}
5. 使用 rgba()
颜色代码设置不透明度.
color_discrete_map={亚洲":'rgba(255,0,0,0.4)'}
6. 覆盖所有设置:
.update_traces(marker=dict(color='red'))
第 2 部分:细节和情节
以下代码段将生成下面的图表,显示所有大陆在不同 GDP 水平下的预期寿命.标记的大小代表不同级别的人口,从一开始就让事情变得更有趣.
情节2:
代码2:
将 plotly.express 导入为 px将熊猫导入为 pd# 数据框,输入df = px.data.gapminder()df=df.query("year==2007")px.scatter(df, x="gdpPercap", y="lifeExp",颜色='大陆',大小='流行',)
为了说明上述方法的灵活性,我们首先更改颜色顺序.由于我们对于初学者只显示 one 类别和 one 颜色,因此您必须等待后续步骤才能看到实际效果.但是现在按照第 1 步使用 color_discrete_sequence=px.colors.qualitative.Alphabet
是相同的图:
1. 用
改变px使用的颜色顺序color_discrete_sequence=px.colors.qualitative.Alphabet
现在,让我们将 Alphabet
颜色序列中的颜色应用到不同的大陆:
2. 使用 color
参数
color = '大陆'
如果您像我一样认为这种特定的颜色序列很容易看,但可能有点难以区分,您可以将您选择的颜色分配给一个或多个大洲,如下所示:
3. 使用
自定义一种或多种可变颜色color_discrete_map={亚洲":'红色'}
这非常棒:现在您可以更改序列并为特别有趣的变量选择任何您喜欢的颜色.但是,如果您想将特定颜色分配给更大的子集,上述方法可能会有点乏味.因此,您也可以通过
5. 使用 rgba()
颜色代码设置不透明度.
现在让我们后退一步.如果您认为 red
很适合亚洲,但可能有点过于强烈,您可以使用 rgba
颜色调整不透明度,例如 'rgba(255,0,0,0.4)'
得到这个:
最后一张图的完整代码:
将 plotly.express 导入为 px将熊猫导入为 pd# 数据框,输入df = px.data.gapminder()df=df.query("year==2007")px.scatter(df, x="gdpPercap", y="lifeExp",color_discrete_sequence=px.colors.qualitative.Alphabet,颜色='大陆',大小='流行',color_discrete_map={亚洲":'rgba(255,0,0,0.4)'})
如果您认为我们现在变得有点过于复杂,您可以再次覆盖所有设置:
6. 覆盖所有设置:
.update_traces(marker=dict(color='red'))
这让我们回到了开始的地方.我希望你会发现这很有用!
包含所有可用选项的完整代码段:
# 导入将 plotly.express 导入为 px将熊猫导入为 pd# 数据框df = px.data.gapminder()df=df.query("year==2007")子集 = {亚洲"、欧洲"、大洋洲"}group_color = {i: 'red' for i in subset}# plotly 表示散点图px.scatter(df, x="gdpPercap", y="lifeExp",大小='流行',颜色='大陆',color_discrete_sequence=px.colors.qualitative.Alphabet,#color_discrete_map=group_colorcolor_discrete_map={亚洲":'rgba(255,0,0,0.4)'})#.update_traces(marker=dict(color='red'))
There are many questions and answers that touch upon this topic one way or another. With this contribution I'd like to clearly show why an easy approch such as marker = {'color' : 'red'}
will work for plotly.graph_objects (go)
, but color='red'
will not for plotly.express (px)
although color is an attribute of both px.Line
and px.Scatter
. And I'd like to demonstrate why it's awesome that it doesn't.
So, if px
is supposed to be the easiest way to make a plotly figure, then why does something as apparently obvious as color='red'
return the error
ValueError: Value of 'color' is not the name of a column in 'data_frame'.
To put it short, it's because color
in px
does not accept an arbitrary color name or code, but rather a variable name in your dataset in order to assign a color cycle to unique values and display them as lines with different colors.
Let me demonstrate by applyig a gapminder dataset and show a scatterplot of Life expectancy
versus GDP per capita
for all (at least most) countries across the world as of 2007
. A basic setup like below will produce the following plot
Figure 1, plot using go
:
The color is set by a cycle named plotly but is here specified using marker = {'color' : 'red'}
Figure 2, code:
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()
So let's try this with px
, and assume that color='red'
would do the trick:
Code 2, attempt at scatter plot with defined color using 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',
)
Result:
ValueError: Value of 'color' is not the name of a column in 'data_frame'. Expected one of ['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap', 'iso_alpha', 'iso_num'] but received: red
So what's going on here?
解决方案First, if an explanation of the broader differences between go
and px
is required, please take a look here and here. And if absolutely no explanations are needed, you'll find a complete code snippet at the very end of the answer which will reveal many of the powers with colors in plotly.express
Part 1: The Essence:
It might not seem so at first, but there are very good reasons why color='red'
does not work as you might expect using px
. But first of all, if all you'd like to do is manually set a particular color for all markers you can do so using .update_traces(marker=dict(color='red'))
thanks to pythons chaining method. But first, lets look at the deafult settings:
1.1 Plotly express defaults
Figure 1, px default scatterplot using px.Scatter
Code 1, px default scatterplot using 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")
Here, as already mentioned in the question, the color is set as the first color in the default plotly sequence available through px.colors.qualitative.Plotly
:
['#636EFA', # the plotly blue you can see above
'#EF553B',
'#00CC96',
'#AB63FA',
'#FFA15A',
'#19D3F3',
'#FF6692',
'#B6E880',
'#FF97FF',
'#FECB52']
And that looks pretty good. But what if you want to change things and even add more information at the same time?
1.2: How to override the defaults and do exactly what you want with px colors:
As we alread touched upon with px.scatter
, the color
attribute does not take a color like red
as an argument. Rather, you can for example use color='continent'
to easily distinguish between different variables in a dataset. But there's so much more to colors in px
:
The combination of the six following methods will let you do exactly what you'd like with colors using plotly express. Bear in mind that you do not even have to choose. You can use one, some, or all of the methods below at the same time. And one particular useful approach will reveal itself as a combinatino of 1
and 3
. But we'll get to that in a bit. This is what you need to know:
1. Change the color sequence used by px with:
color_discrete_sequence=px.colors.qualitative.Alphabet
2. Assign different colors to different variables with the color
argument
color = 'continent'
3. customize one or more variable colors with
color_discrete_map={"Asia": 'red'}
4. Easily group a larger subset of your variables using dict comprehension and color_discrete_map
subset = {"Asia", "Africa", "Oceania"}
group_color = {i: 'red' for i in subset}
5. Set opacity using rgba()
color codes.
color_discrete_map={"Asia": 'rgba(255,0,0,0.4)'}
6. Override all settings with:
.update_traces(marker=dict(color='red'))
Part 2: The details and the plots
The following snippet will produce the plot below that shows life expectany for all continents for varying levels of GDP. The size of the markers representes different levels of populations to make things more interesting right from the get go.
Plot 2:
Code 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',
)
To illustrate the flexibility of the methods above, lets first just change the color sequence. Since we for starters are only showing one category and one color, you'll have to wait for the subsequent steps to see the real effects. But here's the same plot now with color_discrete_sequence=px.colors.qualitative.Alphabet
as per step 1:
1. Change the color sequence used by px with
color_discrete_sequence=px.colors.qualitative.Alphabet
Now, let's apply the colors from the Alphabet
color sequence to the different continents:
2. Assign different colors to different variables with the color
argument
color = 'continent'
If you, like me, think that this particular color sequence is easy on the eye but perhaps a bit indistinguishable, you can assign a color of your choosing to one or more continents like this:
3. customize one or more variable colors with
color_discrete_map={"Asia": 'red'}
And this is pretty awesome: Now you can change the sequence and choose any color you'd like for particularly interesting variables. But the method above can get a bit tedious if you'd like to assign a particular color to a larger subset. So here's how you can do that too with a dict comprehension:
4. Assign colors to a group using a dict comprehension and color_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. Set opacity using rgba()
color codes.
Now let's take one step back. If you think red
suits Asia just fine, but is perhaps a bit too strong, you can adjust the opacity using a rgba
color like 'rgba(255,0,0,0.4)'
to get this:
Complete code for the last plot:
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)'}
)
And if you think we're getting a bit too complicated by now, you can override all settings like this again:
6. Override all settings with:
.update_traces(marker=dict(color='red'))
And this brings us right back to where we started. I hope you'll find this useful!
Complete code snippet with all options available:
# 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'))
相关文章