文章目录(Table of Contents)
简介
这一篇更加详细的介绍一下Plotly的使用. 之前我们从例子的角度出发, 介绍了Plotly的使用. 在这里我们从更基础的地方讲起, 我们会说明graph object和plotly express的关系. 并说一些Plotly的高级用法, 包括如何绘制子图. 如何将不同的内容绘制在同一幅图像中.
这一篇文章我主要参考Plotly的官方教程: Creating and Updating Figures in Python. 我选取里面部分的内容进行讲解, 大家有空还是可以看看原文的.
同时, 这是关于Plotly的第2篇说明, 第1篇主要从一个例子出发, 介绍了Plotly的基本使用, 链接如下: Python数据可视化之Plotly使用
Plotly基础介绍
plotly.py是提供了一个python使用Plotly.js(JavaScript library)这个的接口. 在Plotly.js中, 一个figure与一个JSON文件是对应的. 我们可以看下面的一个例子, JSON文件是如何与Figure对应的.
- fig = {
- "data":[{'type': 'bar',
- 'x': [1,2,3],
- 'y': [1,3,2]}],
- "layout": {"title": {"text": "A Bar Chart"}}
- }
- import plotly.io as pio
- pio.show(fig)
在上面的代码中, 我们可以看到我们定义了一个fig, 是一个字典类型.
- 在data中我们定义了要绘制图像的种类和里面的数值.
- 在layout中我们可以定义图像的布局, 例如标题等.
最终的绘制结果如下所示.
当然, 直接这么进行绘制的话, 会有一些麻烦, 于是我们有一些更高级API来绘制更加复杂的图像.
一些准备
我们首先导入需要使用的库, 后面就不重复进行书写了.
- import plotly.express as px
- import plotly.graph_objects as go
Plotly中的graph objects
与直接使用python中的字典类型来进行绘制, plotly.py提供了一个更加高级的类叫"graph objects"来帮助我们绘图, 与直接使用字典类型来进行绘图相比, 他有以下的好处:
- 使用Graph objects报错更加详细, 如果你有地方参数有问题, 可以有更加详细的报错信息.
- 对于各个属性的修改, 我们可以使用fig['layout']或是fig.layout进行修改.
对于上面的例子, 我们看一下如何使用graph objects来进行实现.
- fig = go.Figure(
- data=[go.Bar(x=[1, 2, 3], y=[1, 3, 2])],
- layout=go.Layout(
- title=go.layout.Title(text="A Bar Chart")
- )
- )
- fig.show()
绘制的结果是和上面的结果是一样的.
同时, graph object还是提供下面两个方法来将图像转换为json或是dict.
- fig.to_json()
- fig.to_dict()
Plotly中的Plotly Express
Plotly Express是提供了一种更加高级的API来创建graph object. 我们还是使用上面的绘制bar的例子来进行说明.
- # 创建数据集
- data_test = pd.DataFrame([[1,1],[2,3],[3,2]], columns=['x','y'])
- # 进行绘图
- fig = px.bar(data_test, x='x', y='y')
- fig.update_layout(title="A Bar Chart") # 这个时候也是可以更新图像的标题
- fig.show()
绘制出来的结果还是一样的.
Plotly更新图像
上面我们说到使用graph object的一个好处就是可以很方便的更新图像. 这个更新可以指向图像中添加新的内容, 或是更改图像的布局等. 我们还是看下面的例子来进行说明.
多组图像绘制在一起-add_trace
首先我们可以使用add_trace的功能, 将多幅图像绘制在一起, 下面我们将barchart和linechart绘制在一起.
- fig = go.Figure()
- fig.add_trace(go.Bar(x=[1, 2, 3], y=[1, 3, 2]))
- fig.add_trace(go.Scatter(x=[1,2,3], y=[2,3,1], mode='lines'))
- fig.show()
与Plotly Express图形组合
当然, 我们也可以向使用Plotly Express绘制的图像添加内容. 因为使用Plotly Express可以绘制出比较好看的图像, 所以我们可以先绘制出一些好的图像, 之后在往里面加一些辅助的图像.
比如下面这个例子, 我们可以首先使用Plotly Express绘制散点图, 接着向里面增加拟合的直线.
- df = px.data.iris()
- fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species")
- fig.add_trace(
- go.Scatter(
- x=[2, 4],
- y=[4, 8],
- mode="lines",
- name='Regression',
- line=go.scatter.Line(color="gray"),
- showlegend=True)
- )
- fig.show()
更加便捷的方式-add_bar等
除了上面提供的增加trace的方法之外, 他还提供了直接添加的方式. 例如可以直接将add_trace改为add_bar等操作, 所以看到不要觉得奇怪就行了, 我们还是看一个例子.
- fig = go.Figure()
- fig.add_bar(y=[2, 1, 3])
- fig.show()
绘制的结果就是柱状图, 就不放图了, 没什么特别的.
更新图像布局-update_layout
除了上面的add_trace之外, 我们还可以update_layout来修改图像的标题, 坐标轴的名称等. 我们可以看下面的一个例子, 来更新标题的名称和标题的字号.
- fig = go.Figure(data=go.Bar(x=[1, 2, 3], y=[1, 3, 2]))
- fig.update_layout(title_text="A Bar Chart",
- title_font_size=30)
- fig.show()
我们还可以使用这个方法来调整x轴的显示, 例如可以转换为log尺度的.
- fig.update_layout(xaxis_type="log")
更新坐标轴-update_xaxes
除了上面图像的标题的更新, 我们还可以对坐标轴进行更新, 例如下面的, 我们选择不显示grid.
- df = px.data.iris()
- fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", facet_col="species")
- fig.update_xaxes(showgrid=False)
- fig.show()
Plotly子图的绘制
基本的子图绘制
有一个很常见的功能就是子图的绘制, Plotly同样是支持子图的绘制的. 绘制子图我们需要使用到下面的类, make_subplots.
- from plotly.subplots import make_subplots
我们看一下下面的这个例子, 看一下具体是如何来绘制子图的.
- fig = make_subplots(rows=1, cols=2)
- fig.add_trace(go.Scatter(y=[4, 2, 1], mode="lines"), row=1, col=1)
- fig.add_trace(go.Bar(y=[2, 1, 3]), row=1, col=2)
- fig.show()
最终的绘制结果如下所示:
子图中包含多幅图像
这个可以有点绕, 就是有一个子图, 子图里面还包含上面的多组图像绘制在一起的操作. 这个我们只需要在同一个格子里进行多次add_trace即可.
- fig = make_subplots(rows=1, cols=2)
- # 1,1
- fig.add_trace(go.Scatter(y=[4, 2, 1], mode="lines"), row=1, col=1)
- fig.add_trace(go.Scatter(y=[3, 4, 2], mode="lines"), row=1, col=1)
- # 1, 2
- fig.add_trace(go.Bar(y=[2, 1, 3]), row=1, col=2)
- fig.show()
最终的效果如下图所示:
关于多幅图像同时更新-update_traces
有的时候我们希望同时更新多幅图像, 这个时候我们就需要使用update_trace来完成相应的操作了. 我们看下面的例子, 首先我们创建一个2*2的子图.
- fig = make_subplots(rows=2, cols=2)
- # 1, 1
- fig.add_scatter(y=[4, 2, 3.5], mode="markers",
- marker=dict(size=20, color="LightSeaGreen"),
- name="a", row=1, col=1)
- fig.add_bar(y=[2, 1, 3],
- marker=dict(color="MediumPurple"),
- name="b", row=1, col=1)
- # 1, 2
- fig.add_scatter(y=[2, 3.5, 4], mode="markers",
- marker=dict(size=20, color="MediumPurple"),
- name="c", row=1, col=2)
- fig.add_bar(y=[1, 3, 2],
- marker=dict(color="LightSeaGreen"),
- name="d", row=1, col=2)
- # 2, 1
- fig.add_scatter(y=[2, 3.5, 4], mode="markers",
- marker=dict(size=20, color="MediumPurple"),
- name="e", row=2, col=1)
- fig.add_bar(y=[1, 3, 2],
- marker=dict(color="LightSeaGreen"),
- name="f", row=2, col=1)
- # 2, 2
- fig.add_scatter(y=[2, 3.5, 4], mode="markers",
- marker=dict(size=20, color="MediumPurple"),
- name="g", row=2, col=2)
- fig.add_bar(y=[1, 3, 2],
- marker=dict(color="LightSeaGreen"),
- name="h", row=2, col=2)
- fig.show()
我们可以使用selector来选定要更新图像的类型, 使用col或者row来选定要更新的子图的范围. 重复的代码我就不写了, 直接写update_traces的部分.
- # update
- fig.update_traces(marker=dict(color="RoyalBlue"),
- selector=dict(type="bar"),
- row=1)
如下图所示, 可以看到第一行的柱状图的颜色发生了改变.
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论