前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Matplotlib 可视化之多图层叠加

Matplotlib 可视化之多图层叠加

作者头像
数据STUDIO
发布2022-04-11 12:48:36
2K0
发布2022-04-11 12:48:36
举报
文章被收录于专栏:数据STUDIO

大家好,我是云朵君!我们一起来看看这么精彩的可视化图表是如何绘制出来的。

定义曲线函数

首先定义出图中随机曲线的绘图函数。

代码语言:javascript
复制
# Some nice but random curves
def curve():
    n = np.random.randint(1, 5)
    centers = np.random.normal(0.0, 1.0, n)
    widths = np.random.uniform(5.0, 50.0, n)
    widths = 10 * widths / widths.sum()
    scales = np.random.uniform(0.1, 1.0, n)
    scales /= scales.sum()
    X = np.zeros(500)
    x = np.linspace(-3, 3, len(X))
    for center, width, scale in zip(centers, widths, scales):
        X = X + scale * np.exp(-(x - center) * (x - center) * width)
    return X

绘图

将比较抽象的曲线函数可视化,更加直观。

代码语言:javascript
复制
np.random.seed(123)
# 获取曲线数据
Y = curve()
X = np.linspace(-3, 3, len(Y))
# 画布准备
fig = plt.figure(figsize=(10, 6),dpi=600)
# 设置画布
ax = plt.subplot(1, 1, 1, frameon=False, sharex=ax)
# 绘制曲线
ax.plot(X, 3 * Y, color="k", 
        linewidth=0.75, zorder=100)
plt.show()

由于该函数的随机性,每次运行都会给出不同的结果:

配置样式

填充颜色、设置坐标轴及坐标轴标签。这里重点是颜色填充函数:Axes.fill_between()

代码语言:javascript
复制
Axes.fill_between(self, x, y1, y2=0, where=None, 
                  interpolate=False, step=None, 
                  *, data=None, **kwargs)

参数:

  • x: 该参数包含用于定义曲线的数据点的水平坐标。
  • y1: 此参数包含用于定义第一条曲线的数据点的y坐标
  • y2: 该参数包含用于定义第二条曲线的数据点的y坐标。它是可选的,默认值为0。
  • where: 此参数是可选参数。它用于排除某些水平区域的填充。
  • interpolate: 此参数也是可选参数。它是错误栏行的线宽,默认值为NONE。
  • step: 此参数也是可选参数。它用于定义填充是否应为阶跃函数。

颜色填充有四种用法

① 基本用法

参数 y1y2 可以是标量,表示给定y值处的水平边界。只要 y1 给出, y2 默认为0。

代码语言:javascript
复制
ax1.fill_between(X, Y, color=color[0])
ax2.fill_between(X, Y, 1, color=color[1])
ax3.fill_between(X, Y, Y2, color=color[2])
② 置信区间

一个常见的应用 fill_between 是置信带的指示。

fill_between 使用填充颜色填充某个区域时,这些颜色可能有点强,以至于宣兵夺主。我们希望淡化填充区域而突出主体。因此设置参数alpha的值,以达到减淡颜色,使该区域半透明的目的。

代码语言:javascript
复制
y_err = X.std() * np.sqrt(1/len(X) +  (X - X.mean())**2 / np.sum((X - X.mean())**2))
ax.fill_between(X, 3*Y - y_err, 3*Y + y_err,
                alpha=0.2, color=cmap(0.3))
③ 选择性填充水平区域

参数where允许指定要填充的 x 范围。它是一个与x大小相同的布尔数组。

仅填充连续 True 序列的x范围。因此,相邻的 TrueFalse 值之间的范围永远不会被填满。当数据点应该表示一个连续的量时,通常不希望出现这种情况。因此,建议设置 interpolate=True,除非数据点的x距离足够细,使上述效果不明显。插值近似于实际的x位置,在那里 where 条件将改变,并扩展填充到那里。

代码语言:javascript
复制
ax1.fill_between(x01, y01, y02, where=(y01 > y02), color='C0', alpha=0.3)
ax1.fill_between(x01, y01, y02,where=(y01 < y02), color='C1', alpha=0.3)

ax2.fill_between(x01, y01, y02, where=(y01 > y02), color='C0', alpha=0.3,
                 interpolate=True)
ax2.fill_between(x01, y01, y02, where=(y01 <= y02), color='C1', alpha=0.3,
                 interpolate=True)
④ 在整个轴上有选择地标记水平区域

同样的选择机制可以应用于填满坐标轴的全部垂直高度。为了不受y极限的影响,我们添加了一个转换来解释数据坐标中的x值和坐标轴坐标中的y值。

下面的示例标记y数据高于给定阈值的区域。

代码语言:javascript
复制
threshold = 0.4
ax.axhline(threshold, color=cmap(0.2), 
           lw=2, alpha=0.7,linestyle='-.')
ax.fill_between(X, 0, 1, where= 3*Y > threshold, 
                color=cmap(0.5), 
                alpha=0.5, 
                transform=ax.get_xaxis_transform())
本案例中,选择第一种常规填充。
代码语言:javascript
复制
# 画布准备
cmap = mpl.cm.get_cmap("Spectral")
color = cmap(0)
ax.fill_between(X, 3 * Y, 0, color=color, zorder=100)
ax.yaxis.set_tick_params(tick1On=False)
ax.set_xlim(-3, 3)
ax.set_ylim(-1, 4)
ax.axvline(0.0, ls="--", lw=0.75, color="black", zorder=250)
ax.text(
    0.0, 1.0,
    "Value %d" % 1,
    ha="left", va="top",
    weight="bold", size=15,
    transform=ax.transAxes,)
ax.yaxis.set_tick_params(labelleft=True)
ax.set_yticks(np.arange(1))
ax.set_yticklabels(["Serie %d" % i for i in range(1, 2)])
for tick in ax.yaxis.get_major_ticks():
  tick.label.set_fontsize(15)
  tick.label.set_verticalalignment("bottom") # 垂直对齐
plt.show()

多图层叠加

zorder 用来控制绘图顺序,其值越大,画上去越晚,线条的叠加就是在上面的。对 plotting 方法的任何调用都可以显式地为该特定项的 zorder 设置值。许多创建可见对象的函数都接受 zorder 参数。或者可以在绘图后调用 set_order() 函数作用在创建的对象上。

接下来开始绘制开篇的这个图,我们发现每条曲线都部分地覆盖了其他曲线,因此为每条曲线设置适当的zorder是很重要的,这样渲染将独立于绘制顺序。

通过横向及纵向循环绘制多个图形,这里注意设置叠放次序参数zorder,最下面的在最上面,然后依次叠放。

代码语言:javascript
复制
rows, cols = 3, 4
ax = None
for n in range(rows):
   # 设置多子图
  ax = plt.subplot(1, rows, n + 1, frameon=False, sharex=ax)
    for i in range(cols):
       Y = curve()
        X = np.linspace(-3, 3, len(Y))
        ax.plot(X, 3 * Y + i, color="k", linewidth=0.75, zorder=100 - i)
        color = cmap(i / cols)
        ax.fill_between(X, 3 * Y + i, i, color=color, zorder=100 - i)

最后多次循环,可以得到下图。

参考资料

Scientific Visualisation-Python & Matplotlib Python数据科学手册

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据STUDIO 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义曲线函数
  • 绘图
  • 配置样式
    • 颜色填充有四种用法
      • ① 基本用法
      • ② 置信区间
      • ③ 选择性填充水平区域
      • ④ 在整个轴上有选择地标记水平区域
      • 本案例中,选择第一种常规填充。
  • 多图层叠加
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档