可视化神器Plotly玩转多子图绘制
Posted 尤尔小屋的猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可视化神器Plotly玩转多子图绘制相关的知识,希望对你有一定的参考价值。
公众号:尤而小屋
作者:Peter
编辑:Peter
可视化神器Plotly玩转多子图绘制
大家好,我是Peter~
很长时间没有Plotly绘图的文章,之前已经介绍如何绘制柱状图、饼图、小提琴图、桑基图等,今天给大家带来的是一篇关于Plotly如何绘制多子图的文章,在一个画布中如何实现多种类型图形的绘制。
Plotly连载文章
多子图绘制
首先看看实际的效果:
Plotly中有两种方式来绘制子图,基于plotly_express和 graph_objects。
但是plotly_express只支持 facet_plots(切面图) 和 marginal distribution subplots(边际分布子图),只有graph_objects是基于make_subplots模块才能够绘制真正意义上的多子图。下面通过实际例子来讲解。
import pandas as pd
import numpy as np
import plotly_express as px
import plotly.graph_objects as go
# 绘制子图
from plotly.subplots import make_subplots
最重要的是要导入make_subplots模块。
基于plotly_express
plotly_express绘制“子图”是通过参数marginal_x
和 marginal_y
来实现的,表示在边际上图形的类型,可以是"histogram", “rug”, “box”, or “violin”。
基于facet_plots
切面图是由具有相同轴集的多个子图组成的图形,其中每个子图显示数据的子集,也称之为:trellis(网格) plots or small multiples。直接上官方英文,感觉更合适,暂时找不到比较恰当的中文来翻译。
不同图形切面展示
先导入内置的消费数据集:
1、基于散点图的切面图形
fig = px.scatter(tips, # 数据
x="total_bill", # xy轴
y="tip",
color="smoker", # 颜色
facet_col="day" # 列方向切面字段
)
fig.show()
2、基于柱状图的切面展示
# 2、柱状图切面
fig = px.bar(tips,
x="size",
y="total_bill",
color="day",
facet_row="smoker" # 行方向切面字段:是否抽烟
)
fig.show()
控制子图个数
3、wrapping column Facets:控制显示元素个数的切面图
当我们指定的某个切面的字段的取值有很多种不同的情况,我们可以通过facet_col_wrap参数来控制每行最多显示的图形个数,wrap可以理解成:被限制的意思,就是每行限制显示多少。
使用内置的GDP数据集:
# 3、被限制每行图形个数的切面图
fig = px.scatter(gdp, # 数据集
x='gdpPercap', # x、y、颜色、点的大小size
y='lifeExp',
color='continent',
size='pop',
facet_col='continent', # 列切面字段
facet_col_wrap=3 # 每行最多3个图形
)
fig.show()
上面的切面图形的col字段是洲,最多只有5个洲。下面的图形选用时间year:
fig = px.scatter(gdp, # 数据集
x='gdpPercap', # x、y、颜色、点的大小size
y='lifeExp',
color='continent',
size='pop',
facet_col='year', # 列切面字段
facet_col_wrap=3 # 每行最多3个图形
)
fig.show()
每行最多显示4个图形:
fig = px.scatter(gdp,
x='gdpPercap',
y='lifeExp',
color='continent',
size='pop',
facet_col='year',
facet_col_wrap=4 # 每行最多4个图形
)
fig.show()
子图坐标轴设置
默认情况下子图的y轴是相同的:
# 独立轴的切面:默认情况是相同的y轴
# 默认下y轴的取值范围相同
fig = px.scatter(tips,
x="total_bill",
y="tip",
color='day',
facet_row="time"
)
fig.show()
通过参数设置不共享y轴:
fig = px.scatter(tips,
x="total_bill",
y="tip",
color='day',
facet_row="time" # 列方向上切面图
)
# 设置不共享y轴,对应的是facet_row
fig.update_yaxes(matches=None)
fig.show()
如果是facet_col在列方向上的切面,则可以设置不共享x轴
fig = px.scatter(tips,
x="total_bill",
y="tip",
color='day',
facet_col="time" # 列方向上切面图
)
# 设置不共享x轴,对应的是facet_col
fig.update_xaxes(matches=None)
fig.show()
子图标题设置
fig = px.scatter(tips,
x="total_bill",
y="tip",
color="time",
facet_col="smoker"
)
fig.show()
通过设置改变子图的标题:
fig = px.scatter(tips,
x="total_bill",
y="tip",
color="time",
facet_col="smoker"
)
# 增加代码:对每行标题通过=切割,取出最后的元素
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.show()
基于边际图Marginal
该方法主要是通过marginal_x和marginal_y来实现的。首先导入数据集:
基于不同图形边际图
1、基于散点图:
fig = px.scatter(iris, # 数据集
x="sepal_length", # 指定xy轴
y="sepal_width",
marginal_x="rug", # 边际图形类型:直方图
marginal_y="histogram" # 轴须图
)
fig.show()
2、基于密度热图的边际图形设置:
fig = px.density_heatmap(
iris, # 数据
x="sepal_width", # 两个轴
y="sepal_length",
marginal_x="violin", # 边际图:小提琴和箱型图
marginal_y="box")
fig.show()
3、边际图颜色设置
fig = px.scatter(iris,
x="sepal_length",
y="sepal_width",
color="species", # 颜色的设置同样适用于边际图
marginal_x="violin",
marginal_y="box",
title="边际图颜色设置")
fig.show()
边际图和切面图连用
fig = px.scatter(
tips,
x="total_bill",
y="tip",
color="sex",
facet_col="day", # 日期字段切面
marginal_x="violin" # 边际图用小提琴图
)
fig.show()
基于graph_objects
graph_objects方式其实是通过make_subplots函数来实现的。一定要先导入:
# 这种方式一定要导入的模块
from plotly.subplots import make_subplots
import plotly.graph_objects as go
基础子图
# 两个基本参数:设置行、列
fig = make_subplots(rows=1, cols=2) # 1行2列
# 添加两个数据轨迹,构成两个图形
fig.add_trace(
go.Scatter(x=[1, 2, 3], y=[5, 10, 15]),
row=1, col=1 # 第一行第一列
)
fig.add_trace(
go.Scatter(x=[20, 30, 40], y=[60, 70, 80]),
row=1, col=2 # 第一行第二列
)
# 设置图形的宽高和标题
fig.update_layout(height=600,
width=800,
title_text="子图制作")
fig.show()
fig = make_subplots(rows=3, cols=1) # 3行1列
# 添加3个数据轨迹
fig.add_trace(
go.Scatter(x=[1, 2, 3], y=[5, 10, 15]),
row=1, col=1 # 1*1
)
fig.add_trace(
go.Scatter(x=[20, 30, 40], y=[60, 70, 80]),
row=2, col=1 # 2*1
)
fig.add_trace(
go.Scatter(x=[50, 60, 70], y=[110, 120, 130]),
row=3, col=1 # 3*1
)
fig.update_layout(height=600,
width=800,
title_text="子图制作")
fig.show()
多行多列子图
多行多列的时候,我们可以指定第一个图形的位置,表示图形从哪里开始。默认左上角是第一个图形的位置。
\\fig = make_subplots(rows=2, cols=2,# 2行2列
start_cell="bottom-left"# 第一个图形的位置,两个选择:bottom-left', 'top-left
)
# 添加4个数据轨迹
fig.add_trace(
go.Bar(x=[1, 2, 3], y=[5, 10, 15]),
row=1, col=1 # 1*1
)
fig.add_trace(
go.Scatter(x=[20, 30, 40], y=[60, 70, 80]),
row=1, col=2 # 1*2
)
fig.add_trace(
go.Scatter(x=[50, 60, 70], y=[110, 120, 130]),
row=2, col=1 # 2*1
)
fig.add_trace(
go.Bar(x=[50, 60, 70], y=[110, 120, 130]),
row=2, col=2 # 2*2
)
fig.update_layout(height=600,
width=800,
title_text="子图制作")
fig.show()
多子图标题设置
很多时候我们要给每个子图取名,用subplot_titles来实现
fig = make_subplots(rows=2, cols=2,
start_cell="bottom-left", # 'bottom-left', 'top-left
subplot_titles=["子图1","子图2","子图3","子图4"] # 每个子图的名字
)
# 添加4个数据轨迹
fig.add_trace(
go.Bar(x=[1, 2, 3], y=[5, 10, 15]),
row=1, col=1 # 1*1
)
fig.add_trace(
go.Scatter(x=[20, 30, 40], y=[60, 70, 80]),
row=1, col=2 # 1*2
)
fig.add_trace(
go.Scatter(x=[50, 60, 70], y=[110, 120, 130]),
row=2, col=1 # 2*1
)
fig.add_trace(
go.Bar(x=[50, 60, 70], y=[110, 120, 130]),
row=2, col=2 # 2*2
)
fig.update_layout(height=600,
width=800,
title_text="多行多列子图制作")
fig.show()
多子图标注Annotations
在子图中我们还可以给数据添加标注:
fig = make_subplots(rows=1, cols=2,
subplot_titles=["子图1","子图2"] # 子图名字
)
# 添加数据
fig.add_trace(
go.Bar(x=[1, 2, 3],
y=[5, 10, 15],
text=["文字1", "文字2", "文字3"], # 标注内容
textposition="inside" # 位置
),
row=1, col=1 # 1*1
)
# 添加数据
fig.add_trace(
go.Scatter(x=[1, 2, 3],
y=[5, 10, 15],
mode="markers+text", # 散点图的数据显示形式
text=["文字4", "文字5", "文字6"], # 标注内容
textposition="bottom center" # 位置
),
row=1, col=2 # 1*2
)
fig.update_layout(height=600,
width=800,
title_text="多子图添加标注")
fig.show()
子图宽度设置
上面绘制的多子图都是大小相同的,我们可以通过参数来进行设置显示不同的大小:column_widths
fig = make_subplots(rows=1,
cols=2,
column_widths=[0.35,0.65], # 重点:两个子图的宽度占比
subplot_titles=["子图1","子图2"] # 名字
)
fig.add_trace(
go.Bar(x=[1, 2, 3],
y=[5, 10, 15],
text=["文字1", "文字2", "文字3"], # 标注内容
textposition="inside" # 位置
),
row=1, col=1 # 1*1
)
# 添加数据
fig.add_trace(
go.Scatter(x=[1, 2, 3],
y=[5, 10, 15],
mode="markers+text", # 散点图的数据显示形式
text=["文字4", "文字5", "文字6"], # 标注内容
textposition="bottom center" # 位置
),
row=1, col=2 # 1*2
)
fig.update_layout(height=600,
width=800,
title_text="多子图添加标注")
fig.show()
共享x轴
共享x轴指的是针对在同列行中的多个图形共享x轴:
fig = make_subplots(rows=3,
cols=1,
# 重点参数
shared_xaxes=True, # 设置共享x轴
vertical_spacing=0.03, # 图之间的间隙大小
subplot_titles=["子图1","子图2","子图3"] # 名字
)
fig.add_trace(
go.Bar(x=[1, 2, 3],
y=[5, 10, 15],
text=["文字1", "文字2", "文字3"],
textposition="inside" # 位置
),
row=1, col=1 # 1*1
)
# 添加数据
fig.add_trace(
go.Scatter(x=[4, 5, 6],
y=[5, 10, 15],
mode="markers+text",
text=["文字4", "文字5", "文字6"],
textposition="bottom center"
),
row=2, col=1 # 2*1
)
# 添加数据
fig.add_trace(
go以上是关于可视化神器Plotly玩转多子图绘制的主要内容,如果未能解决你的问题,请参考以下文章
plotly可视化绘制多子图(subplots)并自定义子图