画图的框架_三体手绘插图

画图的框架_三体手绘插图楔子Python在数据可视化方面有非常多的第三方库,比如matplotlib,pyecharts,bokeh等等,但个人最喜欢的莫过于plotly这个库

9f6873b76eaa50c90418250373c52ef1.png

楔子

1e3c794f61b0ddbf9a6148d01d5cb75e.png

Python 在数据可视化方面有非常多的第三方库,比如 matplotlib, pyecharts, bokeh 等等,但个人最喜欢的莫过于 plotly 这个库。plotly 被称为数据可视化神器,首先它支持很多很多种图表,并且参数可以自由设置,最关键的是画出来的图非常漂亮。毕竟在数据可视化方面,图表的颜值也是很重要的。

很多人认为,pandas 和 plotly 这两个库所带来的影响力甚至超越了 Python 这门语言本身。

下面我们就来全方位介绍一下 plotly 的用法,不过首先要安装它,直接 pip 安装即可,非常方便。

对于学习数据可视化框架而言,本质上就是学习如何使用它来绘制图表。plotly 支持很多图表,包括 3D 动态图等等,这里我们先介绍一些常用的,至于更复杂的图表后续会说。

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

上面几个模块先导入就行,我们的代码会在 jupyter notebook 上运行,可以直接显示图表。至于图表如何保存成图片,我们后续再说。

为了更好地理解 plotly,我们要记住两个核心概念,分别是轨迹和画布。上面导入的 graph_objs 专门用来绘制图表,比如 go.Scatter 是散点图,在 plotly 中,图表被称为轨迹(trace)。而轨迹如果想显示,那么必须显示在画布上,当然一个画布可以显示多个轨迹。

所以结论如下:我们根据自己的需要来创建轨迹,然后再创建一张画布,它是用于展示轨迹(图表)所不可或缺的舞台,然后将轨迹展示在画布上即可。

而我们也可以调整轨迹、画布的一些属性,让它们整体看起来更加的完美,也就是我们说的设置属性参数。plotly 里面图表、画布的属性参数非常多,但我们都会说。而且也正因为如此,图表中任何位置,只要我们不满意都可以进行设置。

下面就来介绍一些常见的图表。

6f196dceab7119ae2231e661b0065083.png

散点图

5df9060f0735917fd83c314b994b349e.png

散点图(scatter)是将数据以点的形式展现在平面直角坐标系上的统计图表,它至少需要两个不同变量,一个沿 X 轴绘制,另一个沿 Y 轴绘制。每个点在 X、Y 轴上都有一个确定的位置。众多的散点叠加后,即可展示数据集的整体景观,从而帮助我们分析两个变量之间的相关性,或找出趋势和规律。此外,我们还可以添加附加的变量,来给散点分组、着色、确定透明度等等。

# 生成100个点 x = np.linspace(0, 2, 100)   y0 = np.random.randn(100) + 5 y1 = np.random.randn(100) y2 = np.random.randn(100) - 5 # 里面的参数一会儿解释 trace0 = go.Scatter(     x=x,  # x 轴的坐标     y=y0,  # y 轴的坐标     mode="markers",  # 纯散点绘图     name="散点"  # 曲线名称 ) trace1 = go.Scatter(     x=x,       y=y1,      # 散点 + 线段绘图     mode="markers + lines",       name="散点 + 线段"  ) trace2 = go.Scatter(     x=x,       y=y2,      mode="lines",  # 线段绘图     name="线段"   )   # 我们看到比较神奇的地方是,Scatter 居然也可以绘制线段 # 是的,如果不指定 mode 为 "markers",默认绘制的就是线段 # 以上就创建了三条轨迹,下面该干什么了?对,创建画布 # 将轨迹组合成列表传进去,因为一张画布是可以显示多条轨迹的 fig = go.Figure(data=[trace0, trace1, trace2]) # 在 notebook 中,直接通过 fig 即可显示图表 fig

看一下画出来的图是什么样子?

de610b3e4ac150a6c07772bc003cd733.png

可以看到比 matplotlib 漂亮多了,在绘制轨迹的时候我们使用了 4 个参数,回顾一下:

  • x:很好理解,就是 x 轴的坐标;

  • y:很好理解,就是 y 轴的坐标;

  • name:轨迹的名称,就是显示在画布右上方的那个;

  • mode:轨迹的种类,主要有三种,”markers” 表示纯散点,”markers+lines” 表示散点加上线段,”lines” 是线段;

然后再来看一个参数 marker,它接收一个字典,用来设置散点的样式。

x = np.linspace(0, 2, 100)   y0 = np.random.randn(100) trace0 = go.Scatter(     x=x,       y=y0,       mode="markers",       name="散点图",     marker={         # 点的大小         "size": 8,         # 点的颜色         "color": "rgba(102, 198, 147, 0.7)",         # 除此之外,还可以设置点的轮廓         "line": {             # 线条大小             "width": 10,               # 线条的颜色             "color": "rgba(1, 170, 118, 0.3)"           }     } ) fig = go.Figure(data=[trace0]) fig

93d32f3e6549cb553d4267bb09b12aea.png

这里我们没有指定 name 参数,所以右上角不会显示轨迹的名称。再来总结一下 marker 参数:

marker = {     # 点的大小     "size": n,     # 点的颜色,可以是 rgba,可以是 rgb;     # 可以是颜色的英文名,比如 green,yellow;     # 可以是一个 16 进制颜色码,比如:#FF6A04     # 以及它还可以是一个元素个数与轨迹的点的个数相同的数组     # 对应着数组中相同的值的多个点,会被标记为同一种颜色     # 在机器学习里面进行聚类的时候,非常常见     "color": "rgba(n1, n2, n3, n4)",     # 点的线条、轮廓     "line": {"width": n, "color": "green"}     # 是否在右侧显示一个颜色条,默认为 False,不显示     "showscale": True   }

基于以上参数,我们可以将散点图的样式绘制得非常漂亮。

问题来了,如果我想添加标题以及坐标轴名称该怎么办?

# 其它代码不变 fig = go.Figure(     data=[trace0],     layout={         "title": "这是标题",         "xaxis_title": "这是x轴",         "yaxis_title": "这是y轴",         # x轴坐标倾斜60度         "xaxis": {"tickangle": 60}     } ) fig

d0d6d13e3918408054cec50a7d79add7.png

我们看到指定 layout 参数即可给画布设置一些额外属性,该参数可以接收一个字典,通过里面的 key 来指定画布属性,比如:

  • title:标题;

  • xaxis_title:x 轴标题;

  • yaxis_title:y 轴标题;

  • xaxis:x 坐标轴的属性,可以传入一个字典,来设置坐标轴,比如:tickangle 就是将坐标倾斜。尤其在坐标值比较长的时候,我们就可以通过倾斜的方式来避免堆叠在一起。角度大于0顺时针,小于0逆时针。

  • yaxis:y 坐标轴的属性,和 x 坐标轴一样,可以设置非常多的属性。具体能设置哪些,后面单独罗列出来;

  • width:画布的宽度;

  • height:画布的高度;

  • template:画布的风格,可以选择 ggplot2, seaborn, simple_white, plotly, plotly_white, plotly_dark, presentation, xgridoff, ygridoff, gridon, none,默认是 plotly;

5576fa30a25cfab57f3753da11b85bb5.gif

散点图的存在意义

散点图常被用于分析变量之间的相关性,如果两个变量的散点看上去都在某条直线附近波动,则称变量之间是线性相关的;如果所有点看上去都在某条曲线(非直线)附近波动,则称变量之间是非线形相关的;如果所有点在图中没有显示任何关系,则称变量之间是不相关的。

如果散点图呈现出一个集中的大致趋势,并且该趋势可以用一条光滑的曲线来近似,那么这个近似的过程就是曲线拟合,而这条曲线则被称为最佳拟合线或趋势线。如果图中存在个别远离集中区域的数据点,那么这样的点被称为离群点或异常值。

26c3219722e09f5fb5b25a47922951f3.png

折线图

5ebbcf451da11797426526c9e6c6a13b.png

折线图(Line)是一个由笛卡尔坐标系、一些点、以及线段组成的统计图表,常用来表示数值随连续时间间隔或有序类别的变化。在折线图中,x 轴通常用作连续时间间隔或有序类别(比如阶段1、阶段2、阶段3);y 轴用于量化的数据,如果为负值则绘制于 y 轴下方;而连线用于连接两个相邻的数据点。

# covid_19_deaths 是数据集,这个不需要关心 # 你完全可以使用其他的数据集代替 trace0 = go.Scatter(     x=covid_19_deaths["date"],       y=covid_19_deaths["count"],  ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark",                         "title": "当前死亡人数"}) fig

fd220d1c5e4d250bad240aba950714fc.png

虽然用的是 go.Scatter,但默认绘制的是折线图。还记得怎么绘制散点图吗?对的,将 mode 指定为 “markers” 即可。

然后是给折线添加样式,我们给散点图添加样式是通过 marker 参数,而给折线添加样式也有对应的参数。

trace0 = go.Scatter(     x=covid_19_deaths["date"],       y=covid_19_deaths["count"],      line={         # 折线的宽度和颜色         "width": 3,           "color": "rgba(255, 30, 186, 1)"      } ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark",                         "title": "当前死亡人数"}) fig

81e85f3537d62493e80614e1a408f3e4.png

此时折线的样式就改变了,但是我们记得之前在设置散点图的时候好像也用到了 line。没错,只不过那个 line 是传给 marker 参数的字典里面的一个 key,用来设置点的线条、或者轮廓的样式。而这里的 line 它是一个参数,和 marker 参数是同级别的,是用来设置折线样式的。

参数 line 里面还可以指定折线的种类,是虚线、实线等等之类的。

trace0 = go.Scatter(     x=covid_19_deaths["date"],       y=covid_19_deaths["count"],      line={         "width": 3,           "color": "rgba(255, 30, 186, 1)",         "dash": "dot"  # 指定为虚线     } ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark",                         "title": "当前死亡人数"}) fig

80bf457d2112f40ab2393349563258fe.png

“dash” 表示线条的种类,可选的 value 如下:

  • “dot”:由点组成的虚线;

  • “dash”:由短线组成的虚线;

  • “dashdot”:由点和短线组成的虚线;

绘制直线的时候,数据可能不是连续的,那么绘制出来的图像就会出现断层。这个时候我们可以指定 connectgaps 参数,举个例子:

x = np.array([1, 2, np.nan, 4, 5])  y1 = x * 3 + 1 y2 = x * 3 + 2 trace0 = go.Scatter(     x=x,       y=y1, ) trace1 = go.Scatter(     x=x,     y=y2,     connectgaps=True ) fig = go.Figure(data=[trace0, trace1],                  layout={"template": "plotly_dark"}) fig

eb4b163c4eb0dad8ea2fab72c0750b69.png

当数据出现了空值的时候,那么折线默认是会出现断层的,而将 connectgaps 指定为 True ,那么会将缺失值两端的点直接相连,使得直线是完整的。

7de9db6552daebf639306595871ff4fa.gif

折线图的存在意义

折线图用于分析事物随时间或有序类别而变化的趋势,如果有多组数据,则用于分析多组数据随时间变化或有序类别的相互作用和影响。折线的方向表示正 / 负变化,折线的斜率表示变化的程度。

2d5c563323fa7465fcbcac6b53c04e7a.png

柱状图

118bd6b3f431ad4e0cfa988f57e38da8.png

柱状图,是一种使用矩形条,对不同类别进行数值比较的统计图表。最基础的柱形图,需要一个分类变量和一个数值变量。在柱状图上,分类变量的每个实体都被表示为一个矩形(通俗来讲就是柱子),而数值则决定了柱子的高度。

trace0 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[17, 400, 16], ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

f5f2a3f4b2ee3b56ffa9ff2ed634e197.png

这是最简单的柱状图,很明显,即便我们什么参数都不加,样式就已经把 matplotlib 给秒杀了。所以先不管 plotly 这个框架的功能如何(很强),光图表的颜值就足以让我们去学习它。

当然我们也可以绘制多个柱状图:

trace0 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[17, 400, 16],     name="bar1" ) trace1 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[86, 90, 96],     name="bar2"     ) fig = go.Figure(data=[trace0, trace1],                 layout={"template": "plotly_dark"}) fig

bb20b04c24a1ccd3de9b1810a229eafb.png

可以看到柱状图并排显示在一起了,此外我们还可以设置层叠柱状图。

trace0 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[17, 400, 16],     name="bar1" ) trace1 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[86, 90, 96],     name="bar2"     ) # 指定 barmode 为 stack,会将柱状图堆叠在一起 # 这里又多了一个 barmode,所以可调节的属性非常多 # 但是不同的属性适用于不同的轨迹,我们需要哪个就设置哪个即可 fig = go.Figure(data=[trace0, trace1],                 layout={"template": "plotly_dark",                         "barmode": "stack"}) fig

53512cee8234c0465d855ba08284ca90.png

所以层叠柱状图是在画布里面设置的,因为两个轨迹要显示在画布上。至于 Bar 里面的参数是设置轨迹本身, 比如我们还可以调节颜色什么的,通过参数 marker 指定:

trace0 = go.Bar(     x=["古明地觉", "芙兰朵露", "古明地恋"],       y=[87, 97, 85],     name="bar1",     marker={         # 除了rgba,还可以通过颜色的名称指定         "color": "pink",         # 指定透明度         # 这里指定透明度的方式,同样适用于Scatter         "opacity": 0.5,           "line": {             "width": 3,  # 轮廓的宽度             "color": "cyan",  # 轮廓的颜色         }     } ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

23dede5738b16fa84a49977552b5eba1.png

柱状图如果想调节样式,也是通过 marker 参数,和 Scatter 里面 marker 一样。

521e5f3c96e19e606586e831c22a38a9.gif

柱状图的存在意义

 

柱状图最适合对分类的数据进行比较,尤其是当数值比较接近时,由于人眼对于高度的感知优于其它视觉元素(如面积、角度等),因此使用柱状图更加合适。

作为人们最常用的图表之一,柱状图也衍生出多种多样的图表形式。例如,将多个并列的类别聚类、形成一组,再在组与组之间进行比较,这种图表叫做分组柱状图或簇状柱形图。还可以将类别拆分成多个子类别,形成堆叠柱状图。再比如将柱形图和折线图结合起来,共同绘制在一张图上,俗称双轴图等等。

408c72a0adc7c1ab16a8582d858541bb.png

水平柱状图

dfe39a22d1741caade7ea8e44b4af80a.png

水平柱状图也叫条形图,和柱状图类似,也是通过 go.Bar 来绘制,只不过需要多加一个参数。

trace0 = go.Bar(     # 方向变了,所以 x 轴和 y 轴的数据也要调换位置     y=["古明地觉", "芙兰朵露", "古明地恋"],       x=[87, 97, 85],     marker={         "color": "pink",         "opacity": 0.5,           "line": {             "width": 3,               "color": "cyan",           }     },     # 指定为水平方向即可     orientation="h" ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

b31d8207b95ddb87d99e95921abc665d.png

柱状图有多高取决于 y 轴,而水平柱状图有多长就取决于 x 轴了,所以此时 x 轴就是代表数值的那一方。至于设置颜色、轮廓等参数,和之前的柱状图一样。

4bb00cecb76642a3e00b3989b4255006.png

面积图

83b4fae878e043a56b3cf0076823db2a.png

面积图,又称区域图,是一种随有序变量的变化,反映数值变化的统计图表,原理与折线图相似。而面积图的特点在于,折线与自变量坐标轴之间的区域,会用颜色或者纹理填充。

绘制面积图依旧使用 Scatter,只需要指定一个 fill 参数即可。

x = np.linspace(0, 2, 100) y0 = np.cos(x) y1 = np.sin(x) trace0 = go.Scatter(     x=x,     y=y0,     name="cos",     mode="markers",      fill="tozeroy" ) trace1 = go.Scatter(     x=x,     y=y1,     name="sin",     # mode还可以设置为none,表示将线段隐藏     mode="none",       fill="tozeroy" ) fig = go.Figure(data=[trace0, trace1],                  layout={"title": "面积图",                          "template": "plotly_dark"}) fig

9d1e6b8fa989f58b3b14e984a6133295.png

我们看到面积图就是将轨迹和 x 轴围成的部分涂上颜色,仔细观察橘色的 sin,线段没了,所以线段或者此时的面积图的边界线就相当于被隐藏掉了。如果不指定 fill,直接指定 mode=”none” 也是可以隐藏的,只不过此时绘制的线段你就看不到了。另外我们看到即使是散点,也是可以围成面积图的,会用线将点拟合起来,再绘制围成的面积图。

然后注意 fill 参数,它的可选值如下:

  • tozeroy:与 x 轴围成的面积;

  • tozerox:与 y 轴围成的面积;

  • toself:与自身围成的面积;

除了这三个可选值之外,其实还有几个,不过一般用不到。我们主要用的还是 tozeroy,绘制和 x 轴围成的面积。

x = np.array([1, 2, 3, 4, 5]) y0 = np.array([2, 6, 9, 7, 3]) y1 = y0 + 1 y2 = y0 + 2 y3 = y0 + 3 trace0 = go.Scatter(     x=x,     y=y0,     name="y0",     fill="tonexty" ) trace1 = go.Scatter(     x=x,     y=y1,     name="y1",     fill="tonexty" ) trace2 = go.Scatter(     x=x,     y=y2,     name="y2",     fill="tonexty" ) trace3 = go.Scatter(     x=x,     y=y3,     name="y3",     fill="tonexty" ) fig = go.Figure(data=[trace0, trace1, trace2, trace3],                 layout={"title": "面积图",                          "template": "plotly_dark"}) fig

28021b024a9e03e1075686ab931e402c.png

还是很简单的。

e3a48253c6348f5c8b0ac97180eae401.gif

面积图的存在意义

面积图可用于多个系列数据的比较,此时面积图的外观看上去类似层叠的山脉,在错落有致的外形下表达数据的总量和趋势。相较于折线图,面积图不仅可以清晰地反映出数据的趋势变化,也能够强调不同类别的数据间的差距对比。

但它的劣势在于,填充会让形状互相遮盖,反而看不清变化。我们上面的数据弄的比较规整,所以看起来很清晰,但实际工作中绘制出来的面积图就不一定了。而一种解决方法是使用有透明度的颜色,来让出覆盖区域。

bfa5a12875a90a299d05840e781366e8.png

甘特图

3e676710b46a7193a467c6cfbda5fdb8.png

甘特图又称横道图,是用来显示项目进度等与时间相关的数据的。直接看个例子就很好理解了:

# 创建甘特图,使用plotly.figure_factory # 然后调用内部的create_gantt即可 import plotly.figure_factory as ff tasks = [     {"Task": "任务A", "Start": "2018-1-1", "Finish": "2018-3-1"},     {"Task": "任务B", "Start": "2018-2-1", "Finish": "2018-5-1"},     {"Task": "任务C", "Start": "2018-2-1", "Finish": "2018-6-1"},     {"Task": "任务D", "Start": "2018-4-1", "Finish": "2018-8-1"},     {"Task": "任务E", "Start": "2018-8-1", "Finish": "2019-1-1"} ] # 但是数据格式有要求,里面是一个列表,列表里面是字典 # 字典包含至少三个键值对,分别是 Task、Start、Finish # 表示任务、开始时间、结束时间,不能是其它的名字 fig = ff.create_gantt(tasks, title="这是甘特图") # 此时会直接返回画布,想调整属性的话 # 通过 fig.layout.update 即可 fig.layout.update({"template": "plotly_dark"}) fig

2647b8b3986aea30542bc510a74ebb47.png

创建甘特图的时候,除了传递一个包含字典的列表,还可以传递 DataFrame,当然列名同样必须是 Task, Start, Finish。

此外我们还可以指定颜色,以及进度。

# 创建甘特图,使用plotly.figure_factory # 然后调用内部的create_gantt即可 import plotly.figure_factory as ff tasks = [     {"Task": "任务A", "Start": "2018-1-1",       "Finish": "2018-3-1", "Complete": "干了一小半"},     {"Task": "任务B", "Start": "2018-2-1",       "Finish": "2018-5-1", "Complete": "干了一半"},     {"Task": "任务C", "Start": "2018-2-1",       "Finish": "2018-6-1", "Complete": "干了一半"},     {"Task": "任务D", "Start": "2018-4-1",       "Finish": "2018-8-1", "Complete": "干了一大半"},     {"Task": "任务E", "Start": "2018-8-1",       "Finish": "2019-1-1", "Complete": "全干完了"} ] # 为不同的进度赋予不同的颜色 colors = {     "干了一小半": "rgb(125, 135, 144)",     "干了一半": "rgb(187, 20, 168)",     "干了一大半": "rgb(14, 199, 250)",     "全干完了": "rgb(250, 1, 144)" } fig = ff.create_gantt(tasks,                        # 为不同的进度赋予不同的颜色                       colors=colors,                       # 表示进度,名字任意                       # 这里我们叫 "Complete"                       index_col="Complete",                        # 显示颜色条                       show_colorbar=True) # fig.data 获取所有的轨迹 # fig.layout 获取画布的属性 fig = go.Figure(fig.data,                  layout={"template": "plotly_dark",                         "title": "我的甘特图"}) fig

4725b3fdd1d78bf362acf81031cebaaf.png

甘特图感觉在工作中用的不是很多,了解一下就好。

e9211af1a8d3f3ffa6200c4b0e97603c.png

直方图

a7c3759244b2f990a32e9bbdd2fde2c0.png

直方图,又称质量分布图,用于表示数据的分布情况,是一种常见的统计图表。一般用横轴表示数据区间,纵轴表示分布情况,柱子越高,则落在该区间的数量越大。根据数据分布状况不同,直方图展示的数据有不同的模式,包括对称单峰、偏左单峰、偏右单峰、双峰、多峰以及对称多峰。

构建直方图,首先要确定组距、对数值的范围进行分区,通俗的说就是划定有几根柱子(例如 0-100 分,每隔20分划一个区间,共5个区间)。接着,对落在每个区间的数值进行频次计算(如落在 80-100 分的 10 人,60-80 分的 20 人,以此类推)。最后,绘制矩形,高度由频数决定。

直方图与上面介绍的柱状图有点相像,但其实是完全不同的。前者反映数据分布情况,后者则不具备此功能,只能对数值进行比较。从数据结构来说,柱状图需要 1 个分类变量,是离散的(如一班、二班、三班),因此柱子间有空隙。但直方图的数据均为连续的数值变量(如成绩),因此柱子间是没有空隙的。

x = np.random.randint(1, 20, 1000) trace0 = go.Histogram(x=x) fig = go.Figure(data=[trace0],                  layout={"title": "直方图",                         "template": "plotly_dark"}) fig

9c748157d641a60810e8b88cbdb0060c.png

横坐标是数值,纵坐标是出现的次数。但是有些不完美,就是跨度太大了,所以我们可以指定 xaxis 属性,让跨度小一些。

x = np.random.randint(1, 20, 1000) trace0 = go.Histogram(     x=x,     # 指定histnorm为probability     # 那么y轴将显示出现的次数所占的比例     histnorm="probability"   ) fig = go.Figure(data=[trace0],                  layout={"title": "直方图",                         "template": "plotly_dark",                         # range表示坐标范围                         # dtick表示相邻坐标之间的差值                         # 这里是 2,所以就是 0 2 4 6...                         "xaxis": {"dtick": 2, "range": [0, 20]}                          }) fig

42b11593fc454c67e3a26f878c9375db.png

忘记说了,其实所有的图表对应的类里面,很多参数都是相同的,比如 marker 设置图表本身的颜色透明度、以及轮廓的颜色、大小,name 设置图表的名称等等,这些参数我们不再赘述,而是会直接使用。

然后我们也可以绘制多个直方图:

x0 = np.random.randn(1000)  x1 = np.random.chisquare(5, 1000) trace0 = go.Histogram(     x=x0,     histnorm="probability",     marker={         "opacity": 0.75     } ) trace1 = go.Histogram(     x=x1,     histnorm="probability",     marker={         "opacity": 0.75     } ) fig = go.Figure(data=[trace0, trace1],                  layout={"title": "直方图",                         "template": "plotly_dark",                         "xaxis": {"dtick": 2, "range": [1, 20]}                          }) fig

471ffc3efdba4b949f6ab85712722062.png

但是我们发现这个直方图貌似有些不对劲,因为 plotly 将多个直方图强制变窄了,我们需要将 barmode 指定为 “overlay”。

x0 = np.random.randn(1000) x1 = np.random.chisquare(5, 1000) trace0 = go.Histogram(     x=x0,     histnorm="probability",     marker={         "opacity": 0.75     } ) trace1 = go.Histogram(     x=x1,     histnorm="probability",     marker={         "opacity": 0.75     } ) fig = go.Figure(data=[trace0, trace1],                  layout={"title": "直方图",                          "template": "plotly_dark",                         "barmode": "overlay"}) fig

483a551c9cfb82ab84768f64fdb8440c.png

如果将 barmode 改成 “stack”,那么就会创建堆叠直方图。

x0 = np.random.randn(1000) x1 = np.random.randn(1000) trace0 = go.Histogram(     x=x0,     histnorm="probability",     marker={         "opacity": 0.75     } ) trace1 = go.Histogram(     x=x1,     histnorm="probability",     marker={         "opacity": 0.75     } ) fig = go.Figure(data=[trace0, trace1],                  layout={"title": "堆叠直方图",                          "template": "plotly_dark",                         "barmode": "stack"}) fig

fcd9cf9b67c3267c9ce54ee6e65120ea.png

最后是累计直方图,它的特点是:第n+1个区间的样本数是第n-1个区间的样本数加上第n个区间的样本数。

x0 = np.random.randn(1000) trace0 = go.Histogram(     x=x0,     histnorm="probability",     marker={         "opacity": 0.75     },     # 指定 cumulative 即可     cumulative={"enabled": True}   ) fig = go.Figure(data=[trace0],                  layout={"title": "累计直方图",                          "template": "plotly_dark",                         "barmode": "stack"}) fig

97bf1d5f5ebd5e95e7fb3a1bb4cbcd60.png

直方图的种类还是蛮多的,但说实话,感觉直方图用的也不是很多。如果只是做简单的报表统计,那么几乎用不到直方图。但我们接下来要介绍的饼图,使用就很广泛了。

2393d964ff0e69bd450d9f0c8912eaf9.png

饼图

35311b5f5e34896ba852701f69cc16d8.png

饼图是一种划分为几个扇形的圆形统计图表。在饼图中,每个扇形的弧长(以及圆心角和面积)大小,表示该种类占总体的比例,并且这些扇形合在一起刚好是一个完全的圆形。

饼图最显著的功能在于表现占比。习惯上,人们也用饼图来比较扇形的大小,从而获得对数据的认知。但是,由于人类对角度的感知能力不如长度,因此在需要准确的表达数值(尤其是当数值接近、或数值很多)时,饼图常常不能胜任,建议用柱状图代替。

# 饼图就很简单了,使用 Pie 这个类 trace0 = go.Pie(     labels=["古明地觉", "芙兰朵露", "古明地恋",              "雾雨魔理沙", "紫妈"],     values=[10, 25, 5, 35, 41] ) fig = go.Figure(data=[trace0],                  layout={"title": "饼图",                          "template": "plotly_dark"}) fig

88b345f2097cc31fa793a9a742a4131e.png

我们还可以设置环形饼图,就是在中间挖一个洞。

trace0 = go.Pie(     labels=["古明地觉", "芙兰朵露", "古明地恋",              "雾雨魔理沙", "紫妈"],     values=[10, 25, 5, 35, 41],     hole=0.7  # 从中心挖掉百分之70的部分 ) fig = go.Figure(data=[trace0],                  layout={"title": "饼图",                          "template": "plotly_dark"}) fig

4c25f5eef7b7ba1991d30a09080ab23f.png

我们还可以将饼图旋转一定角度,因为最上方的两个部分明显是垂直分隔的,另外也可以使某一个部分突出。

trace0 = go.Pie(     labels=["古明地觉", "芙兰朵露", "古明地恋",              "雾雨魔理沙", "紫妈"],     values=[10, 25, 5, 35, 41],     pull=[0, 0, 0, 0, 0.1],  # 突出最后一个     rotation=30,  # 旋转30度     marker={       # 饼图也有marker参数,基本上所有图表都有marker参数       # 散点图可以指定一种颜色来让所有的点都呈现相同的颜色       # 但是饼图的每一部分应该是不同的颜色,这才符合饼图这种图形的意义       # 所以我们要传入一个列表,而数据有五个,那么也要指定五种颜色       # 但是即便不指定五个、或者颜色重复也是可以的       # 如果颜色不够,plotly会帮你补充,颜色多了,会只选列表的前五个       "colors": ["yellow", "green", "cyan", "pink", "blue"],         # 并且这里不叫 color 了,而是叫 colors,因为多个颜色       "line": {           "width": 3,           "color": "white",  # 轮廓颜色       }     } ) fig = go.Figure(data=[trace0],                  layout={"title": "饼图",                          "template": "plotly_dark"}) fig

4acd00221f20363976bd3ce1003865c1.png

作为最常见的图表之一,饼图大量应用于各行各业的报告中。比如一家公司有着 5 个业务,现在要看每个业务的营收占据总营收的比例,那么饼图再合适不过了。

bb5f013d66abb3e2e0c006ef54dac2a7.png

气泡图

b1d8595f9e1a75cbbf2683baf7c7bf45.png

气泡图是一种多变量的统计图表,由笛卡尔坐标系和大小不一的圆组成,可以看作是散点图的变形。在气泡图中,每个气泡都代表着一组三个维度的数据,其中前两个维度决定了气泡在笛卡尔坐标系中的位置(即x,y轴上的值),另外一个则通过气泡的大小来表示。例如,x 轴表示产品销量,y 轴表示产品利润,气泡大小代表产品市场份额百分比。

当然,气泡图也可以容纳更多维的数据,例如用第4个变量决定气泡的颜色、透明度等。

# 生成100个点,x 是横坐标 x = np.linspace(0, 2, 50)   # y 是纵坐标 y = np.random.uniform(1, 8, 50) # x 和 y 确定了气泡的位置 # 而数值的大小,则确定气泡的大小 trace0 = go.Scatter(     x=x,     y=y,     mode="markers",     marker={         # size 还可以是一个数组         # 手动指定每一个气泡的大小         "size": 13 * y / np.min(y),         # color 同样可以是数组         # 值相同的气泡会使用同一种颜色         "color": y,         # 显示颜色条         "showscale": True     } ) fig = go.Figure(data=[trace0],                  layout={"title": "气泡图",                          "template": "plotly_dark"}) fig

31c8b8cfc83258dccb5634616f4474d9.png

气泡图通常用于展示和比较数据之间的关系和分布,通过比较气泡位置和大小来分析数据维度之间的相关性。

气泡图也可以用于二维数据,即 y 轴和气泡大小使用同一维度的数据(y 轴和气泡大小的双视觉编码)。这种情况下,它实际上是作为柱状图的替代,用于对比分类数据,但比柱状图更加简洁美观。

3022afd6179291a7ae22e138d26ca516.png

旭日图

ce1c3b1c069721af21fd0cc058ed9a25.png

旭日图是一种表现层级数据的图表,它以父子层次结构来显示数据,并构成一个同心圆,因此又被成为称为多层饼图。离原点越近,数据的层级越高。换句话说,相邻的两层,内层是外层的父。

同时,一个父可以有多个子,即某一个环形又可以被分割成多个环形,环形的弧度由它在父层中所占比例来决定。若无占比关系,则处理成均分。

labels=["河南省", "信阳市", "郑州市", "洛阳市",         "山东省", "济南市", "青岛市", "烟台市",         "安徽省", "凤阳市", "合肥市", "芜湖市"] parents=["",  "河南省", "河南省", "河南省",          "",  "山东省", "山东省", "山东省",          "",  "安徽省", "安徽省", "安徽省"] # values 为出生了多少万人(数字瞎编的) values=[0, 30, 20, 10,           0, 50, 40, 10,           0, 20, 15, 15]   trace0 = go.Sunburst(     # 注意:每一个层级都要表示     labels=labels,     parents=parents,     values=values ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark"}) fig

aaec43ceabc9560900aa43cbf62cfc93.png

市的父级是省,基于每个市的总人数可以算出省的人数,因此内层的圆对应每个省人数所占的比例。然后每个省根据比例再对应外层的圆的一片扇形区域,每个区域再根据比例划分为不同的子区域。

我们可以绘制很多层,目前有两层。但要注意的是,我们需要将每一层的对应关系都描述出来,比如市的父级是省,那么省的父级呢?这里我们假设省为最高级,那么它的父级就是空字符串,父级的值就写成 0。

然后我们改一下,我们将省的父级设置为中国。

labels=["河南省", "信阳市", "郑州市", "洛阳市",         "山东省", "济南市", "青岛市", "烟台市",         "安徽省", "凤阳市", "合肥市", "芜湖市"] parents=["中国",  "河南省", "河南省", "河南省",          "中国",  "山东省", "山东省", "山东省",          "中国",  "安徽省", "安徽省", "安徽省"] values=[  0,       30,      20,      10,             0,       50,      40,      10,             0,       20,      15,      15]   trace0 = go.Sunburst(     labels=labels,     parents=parents,     values=values ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark"}) fig

fa039e943a689d99f1da01adb610c974.png

然后再来关注 values 里面的几个 0,它们表示啥含义呢?

labels=["河南省", "信阳市", "郑州市", "洛阳市",         "山东省", "济南市", "青岛市", "烟台市",         "安徽省", "凤阳市", "合肥市", "芜湖市"] parents=["中国",  "河南省", "河南省", "河南省",          "中国",  "山东省", "山东省", "山东省",          "中国",  "安徽省", "安徽省", "安徽省"] # 河南省、山东省分别还有 10 万人、20 万人没有统计 # 这些人可能来自于别的市 values=[  10,      30,      20,      10,             20,      50,      40,      10,             0,       20,      15,      15]   trace0 = go.Sunburst(     labels=labels,     parents=parents,     values=values, ) fig = go.Figure(data=[trace0],                  layout={"template": "plotly_dark"}) fig

ee8b9295d8bb7c07472921599ecc74c0.png

旭日图的本质是树状关系,与树图是等价的,因此也被称为极坐标下的矩形树图。它可以在承载大量数据的同时,清晰的显示数据间的结构关系。在许多工具中,旭日图被赋予交互功能,方便读图者自行探索。如支持鼠标悬浮高亮、筛选、显示当前层级等等。

94ac7b8733d619ea8eb0c9af0ae62955.png

桑基图

b721e1d4f0b36479fde7c6498752a415.png

桑基图 (Sankey Diagram),是一种表现流程的示意图,用于描述一组值到另一组值的流向,分支的宽度对应了数据流量的大小。

1869年,查尔斯米纳德绘制了1812年拿破仑征俄图,描绘了拿破仑大军在东进时,兵力是如何一步步削弱的,这也是目前公认较早的桑基图。

1640587a5c92e601f961d629613471b1.png

假设有上面这种数据,我们来看看如何将它绘制成桑基图。

trace0 = go.Sankey(     node={         "pad": 85,         "thickness": 40,         "line": {"color": "green", "width": 0.5},         "label": ["女", "男", "狮子座", "双子座", "巨蟹座"],         "color": ["#f8ade8", "#aff8e9", "#eaf863",                     "#6fe2f8", "#f8d47d"],     },     link={         # source 和 target 中的元素都表示上面 label 的索引         # 两者都是一一对应的,比如只看三个数组中的第一个元素         # (0, 2, 5) 就表示 ("女", "狮子座", 5)         "source": [0, 0, 0, 1, 1, 1],         "target": [2, 3, 4, 2, 3, 4],         "value": [5, 2, 3, 4, 2, 2],         "color": ["rgba(172, 163, 105, 0.6)",                   "rgba(196, 166, 255, 0.6)",                   "rgba(252, 255, 212, 0.6)",                    "rgba(188, 255, 199, 0.6)",                    "rgba(255, 185, 217, 0.6)",                    "rgba(255, 182, 129, 0.6)"],     }, ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

e7c689da781be51abeadf2b491b76a67.png

绘制出来就长这个样子,我们来解释一下这张图。

Sankey 里面的参数 node 就表示这几个节点,键 “pad” 表示节点之间的距离,”thickness” 表示节点宽度,”line” 表示线条,”label” 表示节点的名称,”color” 表示节点的颜色。

参数 link 表示节点之间的连接情况,source 和 target 决定了流向,value 表示每个方向的流量,color 表示颜色。

当然我们这里只有一个流出和一个流入,但其实一个流入还可以作为下一个流入的流出,比如:

af3a93ae44a179f25edc7b19b5798de0.png

以上便是桑基图,适合表现分配情况、归类情况,以及变化和流动情况。

8b7c839da1d2d0dbf9b075febeddf597.png

漏斗图

c8f19898b26114f9c680de66c3a92849.png

漏斗图,形如漏斗,用于单流程分析,在开始和结束之间由N个流程环节组成。漏斗图的起始总是100%,并在各个环节依次减少,每个环节用一个梯形来表示,整体形如漏斗。一般来说,所有梯形的高度应是一致的,这会有助人们辨别数值间的差异。

trace0 = go.Funnel(     y = ["浏览量", "注册用户", "Vip", "SVip"],     x = [20000, 15000, 8000, 2000],     # 以前指定透明度的时候,是通过 marker 参数实现的     # 在 marker 参数里面指定一个 "opacity"     # 但有的图表不行,需要单独使用 opacity 参数     opacity = 0.8,     marker={         # 漏斗每部分的颜色         "color": ["deepskyblue", "tan", "teal", "silver"],         # 轮廓         "line": {             "width": 4,             "color": ["wheat", "wheat", "blue", "wheat"]         }     },     # 漏斗之间的连接部分     connector={"fillcolor": "pink",                "line": {"width": 2, "dash": "dot"}} ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

4eed7fccfa11e23cd809bce6de246529.png

同样的,你也可以绘制多个漏斗图,比如:

76b48c4d1c6770ac0e63ec7122e279cb.png

需要注意的是,漏斗图的各个环节,有逻辑上的顺序关系,同时漏斗图的所有环节的流量都应该使用同一个度量。漏斗图最适宜用来呈现业务流程的推进情况,如用户的转化情况、订单的处理情况、招聘的录用情况等。通过漏斗图,可以较直观的看出流程中各部分的占比、发现流程中的问题,进而做出决策。

06f416a03f444044c334cd9b046c9f86.png

雷达图

5230d40d77d21e6578d9ef479f67085a.png

雷达图是一种显示多变量数据的图形方法,通常从同一中心点开始等角度间隔地射出三个以上的轴,每个轴代表一个定量变量,各轴上的点依次连接成线或几何图形。

雷达图可以用来在变量间进行对比,或者查看变量中有没有异常值。另外,多幅雷达图之间或者雷达图的多层数据线之间,还可以进行总体数值情况的对比。

trace0 = go.Scatterpolar(   r=[3, 5, 3, 4, 5],   theta=["速度", "力量", "技巧", "反应", "心态"],   fill='toself' ) fig = go.Figure(data=[trace0],                 layout={"template": "plotly_dark"}) fig

148ee23fec095260de4e7b8fefc7dd02.png

使用雷达图时,特征类别不能过多,并且特征之间要归一化,或者按照统一标准来标准化。

a9422b1f6228691aa4f01f1b22e46a52.png

热力图

1a40cc94c260c100235bc1e500a6fb4f.png

热力图是一种通过对色块着色来显示数据的统计图表,绘图时需指定颜色映射的规则。例如,较大的值由较深的颜色表示,较小的值由较浅的颜色表示;或者较大的值由较暖的颜色表示,较小的值由较冷的颜色表示等等。

trace0 = go.Heatmap(     x=["星期一", "星期二", "星期三", "星期四", "星期五"],     y=["早上", "中午", "晚上"],     z=[ # 星期一到星期五的早上         [12, 13, 17, 14, 15],         # 星期一到星期五的中午         [32, 33, 37, 34, 35],         # 星期一到星期五的晚上         [22, 23, 27, 24, 25],     ] ) fig = go.Figure(     data=[trace0],     layout={"template": "plotly_dark"}, ) fig

44be50914bb701f538540a8c2e610309.png

我们还可以调整颜色:

trace0 = go.Heatmap(     x=["星期一", "星期二", "星期三", "星期四", "星期五"],     y=["早上", "中午", "晚上"],     z=[[12, 13, 17, 14, 15],         [32, 33, 37, 34, 35],         [22, 23, 27, 24, 25],     ],     colorscale = 'Viridis' )

210084a7e10223cf356f4d0c621d932c.png

通过指定 colorscale,即可选择不同风格的色块,它的可选值如下:

7b7e432aeea59eeb21f9a4f3514ffca7.png

从数据结构来划分,热力图需要 2 个分类字段和 1 个数值字段,分类字段确定 x、y 轴,将图表划分为规整的矩形块,而数值字段决定了矩形块的颜色。

热力图适合用于查看总体的情况、发现异常值、显示多个变量之间的差异,以及检测它们之间是否存在任何相关性。它的优势在于空间利用率高,可以容纳较为庞大的数据。热力图不仅有助于发现数据间的关系、找出极值,也常用于刻画数据的整体样貌,方便在数据集之间进行比较。

但热力图也有缺陷,尽管热力图能够容纳较多的数据,然而人们很难将其中的色块转换为精确的数字。因此当需要清楚知道数值的时候,可能需要额外的标注,plotly 支持这一点,当把鼠标放到色块上时,会显示相应的数值。

0990b19e15d7d672aa3751c823aa7bc2.png

其它轨迹

a97e6ce1412273e0dbbcd07d1a60b7bd.png

我们上面已经介绍了工作中常用的图表,如果你还想知道更多的图表,可以查看 plotly 官网。

https://plotly.com/python/

c6a4e63fbf630105154d86c258ae8540.png

画布属性 layout

ad5bcb920c9c9e77eeac43b0276930a7.png

重点来了,我们创建画布的时候用的是 Figure 类,它里面接收两个参数。第一个参数 data 负责接收轨迹,第二个参数 layout 负责调整画布属性。我们创建完画布之后,也可以通过 fig.data 或 fig.layout 拿到相应的轨迹和画布。

然后我们来看看画布都支持哪些属性。

620b999fbf14251bd4cf238dfbabc10e.png

title

标题,可以是一个字符串,也可以是一个字典。

layout = {     "title": "这是标题" } # 或者传递一个字典,指定标题的同时 # 还可以指定字体、位置 layout = {     "title": {"text": "这是标题",               # 字体(一会单独说)               "font": {"family": "STKaiti", "size": 30},               # 水平位置,0.5 表示居中               "x": 0.5} }

a3f78a79e06a4a7673a6f152bb49f5da.png

xaxis_title、yaxis_title

x 轴名称和 y 轴名称,同样支持字符串和字典。

x = np.linspace(0, 2, 100)   y = np.random.randn(100) trace0 = go.Scatter(     x=x,       y=y,     mode="markers" ) fig = go.Figure(     data=[trace0],     layout={"template": "plotly_dark",             "title": {"text": "我是散点图",                       "font": {"family": "STKaiti", "size": 30},                       "x": 0.5},             "xaxis_title": "我是 x 轴",             "yaxis_title": {"text": "我是 y 轴",                             "font": {"family": "STKaiti",                                       "size": 20, "color": "pink"}},            } ) fig

a4b334ef4c5fb5d4ed6650039b485035.png

我们看到标题和 y 轴的字体变了,但 x 轴没有变。因为 x 轴传递的字符串,它只能表示标题内容,样式则使用默认的。

0e69d7c30d9f98dde4c200521ecbe301.png

ee3155ca769adbbda016a4880a3b7c53.png

这些用表格罗列出来的,就不演示了,可以自己测试一下,看看这些参数的效果。

e03bac318b5da06af34379dae4202148.png

font

字体,和 titlefont 属性一致,通过传递一个字典来指定颜色、大小、种类等等。但 titlefont 的效果只会作用于标题,而这里的 font 会作用于所有地方,比如标题、x 轴和 y轴的名称、坐标刻度等等。

x = np.linspace(0, 2, 100) y0 = np.random.randn(100) + 5 y1 = np.random.randn(100) - 5 trace0 = go.Scatter(     x=x,     y=y0,     name="one" ) trace1 = go.Scatter(     x=x,     y=y1,     name="two" ) fig = go.Figure(     data=[trace0, trace1],     layout={"font": {"color": "cyan",                      "size": 20,                      "family": "stcaiyun"},             "template": "plotly_dark"             } ) fig

ef9e4ae150eff935eec405faa34ceadd.png

所有能看到字的部分,其字体的颜色、大小、类型都变了。

c4d604b706a8054c4ee5a89caa43637f.png

legend

设置展示轨迹名称时的属性。

x = np.linspace(0, 2, 100) y0 = np.random.randn(100) + 5 y1 = np.random.randn(100) - 5 trace0 = go.Scatter(     x=x,     y=y0,     name="one" ) trace1 = go.Scatter(     x=x,     y=y1,     name="two" ) fig = go.Figure(     data=[trace0, trace1],     layout={"legend": {"bgcolor": "orange",                        "font": {"size": 30, "color": "blue"}},             "template": "plotly_dark"             } ) fig

578031831b7548834b8a9bb3f67a5cac.png

ec6164bede6f93557143b38662620245.png

48d2d7996a3361c3309b770f6e3f92f7.png

216d2db32b1efa25f6e4014b9a035b5f.png

paper_bgcolor、plot_bgcolor

分别表示画布背景颜色、和图表背景颜色。

x = np.linspace(0, 2, 100) y0 = np.random.randn(100) + 5 y1 = np.random.randn(100) - 5 trace0 = go.Scatter(     x=x,     y=y0,     name="one" ) trace1 = go.Scatter(     x=x,     y=y1,     name="two" ) fig = go.Figure(     data=[trace0, trace1],     layout={"paper_bgcolor": "yellow",             "plot_bgcolor": "cyan"             } ) fig

42e5023ccd452edbf386eff397115d56.png

99654ed3d731c1b056ae74b330b178d0.png

images

我个人觉得最牛的一个功能,就是可以将图片作为背景。

from PIL import Image x = np.linspace(0, 2, 100) y0 = np.random.randn(100) + 5 y1 = np.random.randn(100) - 5 # 使用 PIL 打开图片 im = Image.open("../lemu.jpg") trace0 = go.Scatter(x=x, y=y0, name="one") trace1 = go.Scatter(x=x, y=y1, name="two") fig = go.Figure(     data=[trace0, trace1],     layout={         "images": [{             # 可以是PIL读取的Image对象,也可以是base64字符             "source": im,               "sizex": 1,             "sizey": 1,             "yanchor": "bottom",             "opacity": 0.3,           }],         "showlegend": False,         "template": "plotly_dark"     }) fig

95015a5a6afee3ac7d9488c35696288c.png

以上就是画布 layout 支持的一些属性,但还有两个最重要没有说,就是 xaxis 和 yaxis。

aef488d5de38c87611f28052004a88f2.png

xaxis 和 yaxis

4895b1e478aae5a6a06b6ce6d20c1b02.png

xaxis 和 yaxis 非常重要,关键的东西我们留到最后,由于它们支持的属性是一样的,都是坐标轴,就一起说了。首先 xaxis 和 yaxis 同样是传递给 layout 的字典里面的 key,但关键的是它们对应的 value 也是一个字典,这个字典里面同样可以支持很多的属性。

color:

颜色,针对于当前坐标轴的刻度

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"color": "red"},         "template": "plotly_dark"     }) fig

95dfd178d5dcbb39c89624f8a812ac27.png

坐标轴刻度变成了红色。

5820d7bac52556174c5ee6f76d4e02b7.png

b9ddc8b4d0b017371fbd5d1ea21d1f71.png

8082e7df9e599af7169fcc497836b0b3.png

gridcolor、gridwidth

网格线颜色和网格线宽度。

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"gridwidth": 5,                    "gridcolor": "cyan"},         "template": "plotly_dark",     }) fig

5f0bddae74aac3e2d8284b76b5b6d17e.png

b081fb8237d39698dde1abbf8c973b27.png

linecolor、linewidth

坐标轴线条颜色与宽度

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"linewidth": 5,                    "linecolor": "cyan"},         "template": "plotly_dark",     }) fig

7fb5518e95fb517d4e72cddcb3689131.png

199371b45d8961afff17c82b06266208.png

rangeslider

范围滑块

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"rangeslider": {"bgcolor": "cyan"}},         "template": "plotly_dark"     }) fig

aa9bfbd8fad1187d5138e9fc86354461.png

下方有一个滑块,可以拖动,然后显示对应的图形部分。

showgrid

是否显示网格。

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"showgrid": False},         "yaxis": {"showgrid": False},         "template": "plotly_dark"     }) fig

906fe4de426a36f8f1e16a33dd20db64.png

5780b201c5bbbf506b93a891ddb1bb0c.png

side

设置坐标轴刻度位置

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"side": "top"},         "yaxis": {"side": "right"},         "template": "plotly_dark"     }) fig

838520fef02d502ff13dd890e5a656b0.png

c35dcac2b3e5cd35fa6428e13901dc43.png

showline:显示线条开关;

spikecolor:峰值数据颜色;

tickangle:刻度倾斜角度,之前用过的。

a43895d86f87ead9b37c0796fcfc6556.png

tickprefix、ticksuffix:刻度前缀和后缀

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {"tickprefix": "<<",                    "ticksuffix": ">>"},         "template": "plotly_dark"     }) fig

40c6aa36b393bb13d673120fc15965ed.png

6f568bfed14e2cf6358f772ef167dc26.png

title、titlefont

设置坐标轴名称,类似于 layout 中的 title 和 titlefont,当然坐标轴名称还可以通过 xaxis_title 和 yaxis_title 指定。

x = np.linspace(0, 2, 100) y = np.random.randn(100) + 5 trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         # title 也可以是一个字典         # 在里面通过 "font" 指定字体         "xaxis": {"title": "我是 x 轴",                   "titlefont": {"color": "cyan", "size": 20}},         "template": "plotly_dark"     }) fig

baa2151e4870acb594680289e3bec998.png

b28af9fb305647dda333600125e8c1c5.png

type:刻度类型

可以是 ‘-‘, ‘linear’, ‘log’, ‘date’, ‘category’, ‘multicategory’ 之一。

zeroline:是否显示零线、就是值全部为 0 的线

对于 xaxis 就是 y 轴,对于 yaxis 就是 x轴。

49db0cdae853ccade6d85b6e19370bef.png

zerolinecolor、zerolinewidth

零线的颜色和宽度

x = np.linspace(0, 2, 100) y = np.random.randn(100) trace0 = go.Scatter(x=x, y=y) fig = go.Figure(     data=[trace0],     layout={         "xaxis": {             "zerolinecolor": "cyan",             "zerolinewidth": 5         },         "yaxis": {             "zerolinecolor": "pink",             "zerolinewidth": 5         },         "template": "plotly_dark"     }) fig

7620df1a80310f7283f4daccd692c420.png

以上就是两个坐标轴支持的属性设置,可以看到支持的属性非常多,而且都可以自定制,只不过很多我们都用不到。

d8c761d24bfeca73a6988c0e81bd8245.png

小结

762868ac4f2fc3049c21b9a8e9b833e0.png

plotly 真的是一个绘图神器,支持大量的图表,当然我们只介绍了一部分,不过它们都是最常用的。在使用 plotly 的时候要记住轨迹和画布两个概念,我们说图表在 plotly 中就是轨迹,然后轨迹需要展示在画布上,而画布有很多属性,这些我们上面介绍的比较详细了,虽然很多都用不到。

然后就是 plotly 的图表保存问题,我这里都是直接在 jupyter 上生成,然后下载下来的。至于如何用 plotly 的 API 来生成图片,以及多图绘制,我们下一篇文章再说。

申明:本文中对一些图表所做的概念上的解析,来自于网站 “图之典” ,这是由一些爱好数据可视化的人创建的。里面对图表进行了概念上的详细描述,包括来源、适用场景、以及不适用场景等等,都做了详细的说明。如果你喜欢数据可视化,那么这个网站你一定不能错过。

写在最后,截止到 2022年11月20号,我的公众号关注人数突破 3000 了(喜大普奔)。尽管和其他号主相比,我连人家的二十分之一、三十分之一都不到,但也很开心了。其实我涨粉的主要途径也全靠同行转发,在其他号主转发我文章的时候吸一波粉。

总之,今后我也会努力地输出更多内容,认真写好每一篇文章。

猫哥注:推荐大家关注“古明地觉的编程教室”,宝藏公众号!(当然“Python猫”也是*^_^*)

 

今天的文章
画图的框架_三体手绘插图分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/80340.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注