可视化神器plotly:子图的绘制(代码片段)

traditional traditional     2023-04-11     705

关键词:

楔子

下面我们来进行高级图表的绘制,说是高级图表,其实也不算高级。以下代码在jupyter notebook上运行,先导入以下模块

import plotly as py
import plotly.graph_objs as go
import numpy as np
import pandas as pd
import datetime

时间序列

plotly对时间的支持特别友好,即支持字符串格式、也支持日期格式,而且使用起来比较简单。

x0 = [datetime.date(2018, 1, 1),
     datetime.date(2018, 2, 1),
     datetime.date(2018, 3, 1),
     datetime.date(2018, 4, 1),
     datetime.date(2018, 5, 1)
    ]
x1 = ["2018-1-1", "2018-2-1", "2018-3-1", "2018-4-1", "2018-5-1"]

trace0 = go.Scatter(x=x0, y=[1, 2, 3, 4, 5], name="trace_date")
trace1 = go.Scatter(x=x0, y=[2, 3, 4, 5, 6], name="trace_string")
fig = go.Figure(data=[trace0, trace1])
fig

技术图片

从代码中可以看出,只要是日期、或者符合时间格式的字符串,plotly就会自动识别为日期格式。

表格

还记得我们之前创建甘特图吗?我们用到了plotly.figure_factory,创建表格也是如此。

import plotly.figure_factory as ff

data= [
    ["姓名", "年龄", "性别"],
    ["古明地觉", 17, "女"],
    ["古明地恋", 16, "女"],
    ["椎名真白", 18, "女"],
    ["坂上智代", 19, "女"],
    ["雨宫优子", 16, "女"],
]

fig = ff.create_table(data)
fig

技术图片

神奇的是,里面还可以添加一些html属性。

import plotly.figure_factory as ff

data= [
    ["姓名", "年龄", "性别"],
    ['<a href="http://www.baidu.com">古明地觉</a>', 17, "女"],
    ["古明地恋", 16, "女"],
    ["椎名真白", 18, "女"],
    ["坂上智代", 19, "女"],
    ["雨宫优子", 16, "女"],
]

fig = ff.create_table(data)
fig

技术图片

点击古明地觉即可跳转到百度页面,会在新标签页中打开

使用pandas

import plotly.figure_factory as ff
from sqlalchemy import create_engine
engine = create_engine("postgresql://postgres:zgghyys123@localhost:5432/postgres")
df = pd.read_sql("select * from t_case", engine)

# 直接将DataFrame传进去即可
fig = ff.create_table(df)
fig

技术图片

如果是DataFrame,那么列名就是这里的表头,但是我们看到索引貌似没了,那么如何将索引也显示在上面呢?

import plotly.figure_factory as ff
from sqlalchemy import create_engine
engine = create_engine("postgresql://postgres:zgghyys123@localhost:5432/postgres")
df = pd.read_sql("select * from t_case", engine)

# 直接将DataFrame传进去即可
fig = ff.create_table(df, index=True, index_title="自增数字")
fig

技术图片

多图表

多图表其实在前面博客中已经说了,这里再简单提一嘴。

x = list("abcde")
y0 = [1, 2, -2, 2, -3]
y1 = [1, 2, 3, 4, 5]

trace0 = go.Bar(x=x, y=y0, name="bar")
trace1 = go.Scatter(x=x, y=y1, name="line")
fig = go.Figure(data=[trace0, trace1])
fig

技术图片

多个坐标轴

我们上面的多个图表是显示在相同坐标轴上面的,但是如果两个轨迹的数值相差比较大、还使用这种方法,那么plotly为了显示所有的轨迹,就会把坐标轴往大的方向调整,于是就会造成数值小的轨迹不明显。我们举个栗子看一下就很直观了:

x0 = np.linspace(1, 100, 5)
x1 = np.linspace(0, 1000, 5)
y0 = x0 ** 2 + x0 + 1
y1 = x1 ** 2 + x1 + 1

trace0 = go.Scatter(x=x0, y=y0)
trace1 = go.Scatter(x=x1, y=y1)
fig = go.Figure(data=[trace0, trace1])
fig

技术图片

一条轨迹我们指定的数据是0到1000,一条是0到100。但是plotly为了展示所有的轨迹,坐标轴上刻度会按照轨迹的数值大的一方来显示,因此这就造成了数值小的轨迹的局部细节展示不出。所以在轨迹的数值相差比较大的时候,我们需要绘制第二个坐标轴。

绘制第二个坐标轴非常简单,只需要在layout中指定一个xaxis2和yaxis2即可,同理第三个坐标轴就是xaxis3和xaxis3,以此类推。

x0 = np.linspace(1, 100, 5)
x1 = np.linspace(0, 1000, 5)
y0 = x0 ** 2 + x0 + 1
y1 = x1 ** 2 + x1 + 1

trace0 = go.Scatter(x=x0, y=y0)
# 我们虽然在layout中传入xaxis2和yaxis2创建了第二坐标轴,但是还要指明到底是哪个轨迹使用
# 因此要在轨迹上显式地通过xaxis和yaxis指明,到底是哪个轨迹使用哪个坐标轴
# 但是在指定的时候,第二坐标轴直接写x2、y2即可。默认的坐标轴是第一坐标轴、也就是最原始的那个坐标轴
trace1 = go.Scatter(x=x1, y=y1, yaxis="y2", xaxis="x2")
fig = go.Figure(data=[trace0, trace1],
                layout=
                    # 由于在同一个画布上,所以网格会重叠,我们将其中的一个轴的网格给隐藏掉
                    # 以及zeroline,这些参数都是关于视觉上的,对于表达数据则无影响
                    # 具体如何影响图表的模样,可以自己去试一下
                    "xaxis": "title": "trace0的x轴", "showgrid": False, "zeroline": False,
                    "yaxis": "title": "trace0的y轴", "showgrid": False,
                    # 这里就是第二坐标轴的x轴了
                    "xaxis2": "title": "trace1的x轴", 
                               "side": "top",  # 这个很重要,要设置方向,显然设置为上方
                               # 必须要写,否则图像无法显示,同理下面的yaxis也是类似
                               "overlaying": "x",
                    "yaxis2": "title": "trace1的y轴", 
                               # 第二y轴要设置在右边
                               "side": "right", 
                               "overlaying": "y"
                 
               )
fig

技术图片

此时就绘制出来了,因为现在两个轨迹的坐标不是同一个坐标了。但是它们之间的规律是一样的,再加上又显示在同一个画布上,所以轨迹是差不多重合的。

绘制子图(方式一)

说实话,共享坐标轴的方式展示多图表还不是很常见,常见的是一个画布分为多个区域,每个区域展示各自的图表。就可以想象成之前的一张画布显示一个轨迹,然后把多个画布放在一起显示。这样,它们各自的坐标轴、标题等属性都是独立的。

# 创建子图使用make_subplots
from plotly.subplots import make_subplots

trace0 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace1 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6])
trace2 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace3 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6])

fig = make_subplots(rows=2,  # 将画布分为两行
                    cols=2,  # 将画布分为两列
                    subplot_titles=["trace0的标题", 
                                    "trace1的标题", 
                                    "trace3的标题", 
                                    "trace4的标题"],  # 子图的标题
                    x_title="x轴标题",
                    y_title="y轴标题"
                   )
# 添加轨迹
fig.append_trace(trace0, 1, 1)  # 将trace0添加到第一行第一列的位置
fig.append_trace(trace1, 1, 2)  # 将trace1添加到第一行第二列的位置
fig.append_trace(trace2, 2, 1)  # 将trace2添加到第二行第一列的位置
fig.append_trace(trace3, 2, 2)  # 将trace3添加到第二行第二列的位置
fig

技术图片

此时我们就成功绘制出来了子图,但是有一点不完美的地方是,它的这个坐标轴的标题是针对整体的。我可不可以对不同的坐标轴施加不同的描述呢?显然是可以的。

但是我们这里需要再补充一下,我们之前创建画布的时候是通过go.Figure,然后将画布参数通过字典的方式先写好,然后传给layout。但是事实上我们也可以后续在进行添加的,比如fig["layout"]["xaxis"].update("title": "x坐标轴"),这样做也是可以的。fig["data"]拿到的就是所有的轨迹,我们也可以往里面加入新的轨迹,fig["layout"]则是拿到的画布的属性,一个字典,我们同样可以往里面添加、删除属性。

之所以说这些,就是因为make_subplots里面没办法直接传递layout,只能通过创建出来的画布、手动获取里面的layout、然后添加。

from plotly.subplots import make_subplots

trace0 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace1 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6])
trace2 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace3 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6])

fig = make_subplots(rows=2,  
                    cols=2,  
                    subplot_titles=["trace0的标题", 
                                    "trace1的标题", 
                                    "trace2的标题", 
                                    "trace3的标题"], 
                   )
fig.append_trace(trace0, 1, 1)  
fig.append_trace(trace1, 1, 2)  
fig.append_trace(trace2, 2, 1)  
fig.append_trace(trace3, 2, 2)  
# 创建了四个子图,自动就会有四个坐标轴。
# 每个轨迹占一个,因此这种情况我们是不需要在轨迹里面通过xaxis和yaxis来指定到底使用哪一个坐标轴的,因为已经分配好了
fig["layout"]["xaxis"].update("title": "trace0的x轴", "titlefont": "color": "red")
fig["layout"]["yaxis"].update("title": "trace0的y轴", "titlefont": "color": "red")
fig["layout"]["xaxis2"].update("title": "trace1的x轴", "titlefont": "color": "green")
fig["layout"]["yaxis2"].update("title": "trace1的y轴", "titlefont": "color": "green")
fig["layout"]["xaxis3"].update("title": "trace2的x轴", "titlefont": "color": "pink")
fig["layout"]["yaxis3"].update("title": "trace2的y轴", "titlefont": "color": "pink")
fig["layout"]["xaxis4"].update("title": "trace3的x轴", "titlefont": "color": "yellow")
fig["layout"]["yaxis4"].update("title": "trace3的y轴", "titlefont": "color": "yellow")

fig["layout"]["template"] = "plotly_dark"
fig

技术图片

绘制子图(方式二)

我们下面这种绘制子图的方式有点类似于共享坐标轴的方式,主要在于内部的一个domain参数。

trace0 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace1 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6], xaxis="x2", yaxis="y2")

fig = go.Figure(data=[trace0, trace1],
                layout="xaxis": "domain": [0, 0.6],  # 指定第一幅图的范围是0到百分之60
                        "xaxis2": "domain": [0.7, 1],  # 第二幅图的范围是百分之70到百分之百
                        
                        # 这个参数可能有些费解,它是指定y轴位置的,如果是通过"side": "right"的话,那么这个轴会在第一幅图的右边
                        # 通过"anchor": "x2",那么y轴就是像现在这样出现在第二幅图的左边。
                        "yaxis2": "anchor": "x2"  
                          
               )

fig

技术图片

这种绘制子图的方式可能不是容易让人理解,主要就在于里面的domain参数。我们之前通过这种方式可以认为是两张子图(都占据全部位置)重合了,现在通过domain将两幅子图分开了。因此相比make_subplots,这种绘制子图的方式有点让人费解,而且我们还要计算好位置。

但是这种绘制子图的方式的好处就在于我们可以自定义子图的位置,我们使用make_subplots的时候,多个子图大小的是一样的,并且间隔什么的是等分的,但是domain这种方式就不同了。

trace0 = go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])
trace1 = go.Scatter(x=[2, 3, 4, 5, 6], y=[2, 3, 4, 5, 6], xaxis="x2", yaxis="y2")

fig = go.Figure(data=[trace0, trace1],
                layout=# xaxis不指定,则默认是占据全部
                        # 我们只指定xaxis2和yaxis2
                        # 我们之前好像在xaxis里面没有指定anchor,那是因为当时x轴就是在底部,或者说y轴占据了整个垂直方向
                        # 但是现在不一样了,我们还要指定y轴的范围
                        "xaxis2": "domain": [0.6, 0.95], "anchor": "y2",  
                        "yaxis2": "domain": [0.1, 0.4], "anchor": "x2"  
                          
               )

fig

技术图片

我们看到一张图出现在了另一张图的里面,这是因为第一坐标轴、也就是默认的轴它的范围是百分之百的,而我们指定了第二坐标轴的x方向和y方向只占据了一部分,那么使用该坐标的轴的轨迹就会显示在局部,而不是像之前一样占满全部范围。而绘制出类似于make_subplots的方式,则是让每个轴domain不重合即可,然后计算好位置。所以这种方式应该说更强大,只不过对于绘制标准的、一个子图占一个坑、规规整整的排列的多个子图的话,还是推荐使用make_subplots。而domain这种方式这是让我们自定义的。

而最后再说说那个轴里面的anchor,这个老铁主要是空值坐标轴的刻度显示在什么地方的。我们之前在绘制多个坐标轴的时候,直接使用的side,那是因为坐标轴所在的两幅图的大小是一样的,但是现在不一样了。所以我们需要指定第n坐标轴的x轴的"anchor"为yn、第n坐标轴的y轴的"anchor"为xn。

总结

我们高级部分就说到这里,总体来说plotly是非常强大的,但是里面的参数真的很多,掌握起来也不是件容易的事情,加油。

可视化神器plotly绘制热力图(代码片段)

公众号:尤而小屋作者:Peter编辑:Peter大家好,我是Peter~之前更新了很多关于Plotly绘图的文章。今天带来的文章是基于官网和实际案例来讲解如何绘制不同需求下的热力图。Plotly中绘制热力图有3种方式:heatma... 查看详情

可视化神器plotly绘制树状图(代码片段)

大家好,我是Peter~今天给大家带来的是一篇关于Plotly绘图的文章:如何使用Plotly来绘制矩形树状图Plotly文章目前Plotly的文章更新到第17篇,推荐几篇文章:闲聊为什么Peter一直坚持写Plotly的文章?国庆节前有位... 查看详情

可视化神器plotly绘制3d图(代码片段)

公众号:尤而小屋作者:Peter编辑:Peter大家好,我是Peter~本文中重点介绍的是如何利用plotly来绘制3D图形。在3D图形中一般是包含3个轴的:x、y、z。在Plotly中绘图的时候,我们对layout布局进行设置的时候&#x... 查看详情

再见matplotlib,可视化神器plotly绘制图表的太酷炫了(代码片段)

数据分析离不开数据可视化。我们最常用的就是pandas,matplotlib,pyecharts当然还有Tableau,最近看到一篇文章介绍plotly制图后,我感觉写的不够简洁明了。今天就给大家分享利用可视化神器Plotly绘制酷炫图表,欢... 查看详情

Plotly:如何在子图上绘制烛台图?

】Plotly:如何在子图上绘制烛台图?【英文标题】:Plotly:Howtoplotcandlestickchartsonasubplot?【发布时间】:2022-01-1419:32:01【问题描述】:我正在尝试绘制一个包含14个加密货币数据烛台图的子图。(https://www.kaggle.com/c/g-research-crypto-foreca... 查看详情

python如何绘制子图的同时绘制双坐标轴图像

请问,绘制4*4的子图,在每一个子图上再绘制双y坐标轴(如图一是绘制好的单一轴的图),应该怎么画呢图二为当前绘制子图的代码用subplots替代subplot,因为在两者都可以画子图的情况下,subplots也可以同时画双y轴。fig,ax=plt.sub... 查看详情

可视化神器plotly美化表格(代码片段)

公众号:尤而小屋作者:Peter编辑:Peter可视化神器Plotly美化表格有时候看到一份表格,没有任何的颜色修饰,总觉得缺点美观效果。在Excel中我们可以直接对字体的颜色、大小等进行设置,还可以进行单元... 查看详情

python-matplotlib可视化——多方面自定义统计图绘制(代码片段)

Python-Matplotlib可视化(7)——多方面自定义统计图绘制前言多个子图的合成为每个子图添加标题子图合成的另一种方法更简洁的方法等比例缩放坐标轴设置坐标轴范围设置图形比例插入子图系列链接前言在系列博文的中&#... 查看详情

plotly可视化绘制多图(multiplot)(代码片段)

plotly可视化绘制多图(multiplot)# plotly可视化绘制多图(multiplot)importplotlyaspyimportplotly.graph_objsasgo#----------predefpyplt=py.offline.plotx=list('ABCDEF')trace1 查看详情

python+matplotlib绘制具有多个子图的图表(代码片段)

目录1.示例 2.向示例中添加元素2.1添加标题 2.1.1调整标题位置 2.2添加图例2.3添加文本2.3.1单行文本​编辑 2.3.2 多行文本 2.4添加坐标轴名称 2.5坐标轴范围设置1.示例本示例来自于matplotlib官网,大家可以参考网站:https... 查看详情

python+matplotlib绘制具有多个子图的图表(代码片段)

目录1.示例 2.向示例中添加元素2.1添加标题 2.1.1调整标题位置 2.2添加图例2.3添加文本2.3.1单行文本​编辑 2.3.2 多行文本 2.4添加坐标轴名称 2.5坐标轴范围设置1.示例本示例来自于matplotlib官网,大家可以参考网站:https... 查看详情

plotly_express:新一代可视化神器,精美动态可视化图表仅需一行代码!(代码片段)

...工具!Plotly_Express快速入门Plotly_Express是新一代的高级可视化神器,它是plotly.py的高级封装,内置了大量实用、现代的绘图模板。使用者只需要 查看详情

plotly可视化绘制混合图(代码片段)

plotly可视化绘制混合图#混合图多种可视化形式融合在一个图形中;fromplotly.graph_objsimport*importplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plotimportpandasaspd#readinvolcanodatabasedatadf=pd.read_excel(r\'volcano_db.x 查看详情

plotly可视化绘制共享坐标轴图(代码片段)

plotly可视化绘制共享坐标轴图#plotly绘制共享坐标轴图;importplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plottrace1=go.Scatter(x=[0,1,2],y=[10,11,12])trace2=go.Scatter(x=[2,3,4],y=[100,110,120],yaxis=\'y2\')trace 查看详情

plotly可视化绘制多子图(subplots)(代码片段)

plotly可视化绘制多子图(subplots)#多子图;fromplotlyimporttoolsimportplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plottrace1=go.Scatter(x=[1,2,3],y=[4,5,6],mode=\'markers+text+lines\',text=[\'A\',\'B\',\' 查看详情

plotly可视化绘制嵌入式子图(代码片段)

plotly可视化绘制嵌入式子图#嵌入式子图importplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plottrace1=go.Scatter(x=[1,2,3],y=[4,3,2])trace2=go.Scatter(x=[20,30,40],y=[30,40,50],xaxi 查看详情

plotly可视化绘制双子图(subplots)(代码片段)

plotly可视化绘制双子图(subplots)#双子图fromplotlyimporttoolsimportplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plottrace1=go.Scatter(x=[1,2,3],y=[4,5,6])trace2=go.Scatter(x=[20,30,40],y=[50,60,70],)fig= 查看详情

plotly可视化绘制多坐标轴图(代码片段)

plotly可视化绘制多坐标轴图 #绘制多坐标轴图;importplotlyaspyimportplotly.graph_objsasgopyplt=py.offline.plottrace1=go.Scatter(x=[1,2,3],y=[4,5,6],name=\'yaxis1数据\')trace2=go.Scatter(x=[2,3,4],y=[40,50,60],name=\'y 查看详情