Python图形可视化进阶二

定制化网格

使用 matplotlib.pyplot.grid 来设置网格的可见度、密度和风格,或者是否显示网格。

示例:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
from matplotlib.cbook import get_sample_data


def get_demo_image():
    f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
    # z 是一个大小为 15x15 的 numpy 数组
    Z = np.load(f)
    return Z, (-3, 4, -4, 3)


def get_grid(fig=None, layout=None, nrows_ncols=None):
    assert fig is not None
    assert layout is not None
    assert nrows_ncols is not None

    grid = ImageGrid(fig, layout, nrows_ncols=nrows_ncols,
                    axes_pad=0.05, add_all=True, label_mode="L")
    return grid


def load_images_to_grid(grid, Z, *images):
    min, max = Z.min(), Z.max()
    for i, image in enumerate(images):
        axes = grid[i]
        axes.imshow(image, origin="lower", vmin=min, vmax=max,
                  interpolation="nearest")

fig = plt.figure(1, (8, 6))
grid = get_grid(fig, 111, (1, 3))
Z, extent = get_demo_image()

# 将图像进行切片
image1 = Z
image2 = Z[:, :10]
image3 = Z[:, 10:]

load_images_to_grid(grid, Z, image1, image2, image3)

plt.draw()
plt.show()

在这里插入图片描述

示例详解:

  • 在函数 get_demo_image 中,我们从 matplotlib 的样本数据目录中加载数据。
  • grid 列表保存了 axes 网格(此例中是 ImageGrid )。
  • 变量 image1image2image3 保存了 Z 的切片数据,这些数据是根据 grid 列表的多个坐标轴切分的。
  • 循环遍历所有的网格,调用标准的 imshow() 方法绘制出 image1、image2、image3R 的数据。
  • matplotlib 确保所有图形的渲染是整洁的,排列是整齐的。

创建高线图

  • 等高线图(contour plot)显示的是矩阵的等值线(isolines)。
  • 等值线是用数值相等的各点连成的曲线。数值通过一个有两个参数的函数获得。

基础知识

  • Z 矩阵的等高线图由许多等高线表示,这里的 Z 被视为相对于 X-Y 平面的高度。
    Z 的最小值为 2,并且必须包含至少两个不同的值。
  • 等高线图的缺陷之一是如果在编码时不为等值线添加标签,它将毫无意义,
    因为我们不能分辨出最高点和最低点,或者找出局部极小值。
  • 我们需要为等高线添加标签。可以使用标签(clabel())或者 colormaps 为等值线添加标签。
    如果你的输出媒介允许使用颜色,colormaps 是首选,因为观察者将更容易理解数据。
  • 等高线图的另一个风险是如何选择要绘制的等值线数量。
    如果选择的太多,图表就会变得太密集从而难以理解;
    如果选择的太少,将丢失信息,从而对数据做出不同的理解。
  • 函数 contour() 会自动猜测出将绘制多少等值线,但我们也可以指定数量。
    matplotlib 中,用 matplotlib.pyplot.contour 绘制等高线图。
    contour() 函数可以有不同的调用签名(如下表所示),这取决于我们拥有的数据和(或者)我们想可视化的属性。
调用签名描述
contour(Z)绘制 Z(数组)的等高线。自动选择水平值
contour(X, Y, Z)绘制 X、Y 和 Z 的等高线。X 和 Y 数组为 (x, y) 平面坐标(surface coordinates)
contour(Z, N)绘制 Z 的等高线,其中水平数由 N 决定。自动选择水平值
contour(X, Y, Z, N)绘制 Z 的等高线,其中水平数由 N 决定。自动选择水平值
contour(Z, V)绘制等高线,水平值在 V 中指定
contour(X, Y, Z, V)绘制等高线,水平值在 V 中指定
contour(…, V)填充 V 序列中的水平值之间的 len (V) - 1 个区域
contour(Z, **kwargs)使用关键字参数控制一般线条属性(颜色、线宽、起点,颜色映射表(colormap)等)

X、Y 和 Z 的形状和维度存在一定的限制。例如,X 和 Y 可以是二维的,与 Z 形状相同。
如果它们是一维的,则 X 的长度等于 Z 的列数,Y 的长度将等于 Z 的行数。

示例:

  1. 实现一个方法来模拟信号处理器。
  2. 生成一些线性信号数据。
  3. 把数据转换到合适的矩阵中供矩阵操作使用。
  4. 绘制等高线。
  5. 添加等高线标签。
  6. 显示图形。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt


def process_signals(x, y):
    return (1 - (x ** 2 + y ** 2)) * np.exp(-y ** 3 / 3)

x = np.arange(-1.5, 1.5, 0.1)
y = np.arange(-1.5, 1.5, 0.1)

# 制作点网格
X, Y = np.meshgrid(x, y)

Z = process_signals(X, Y)

# 等高线的数量
N = np.arange(-1, 1.5, 0.3)

# 添加带有标签的等高线
CS = plt.contour(Z, N, linewidths=2, cmap=mpl.cm.jet)
plt.clabel(CS, inline=True, fmt='%1.1f', fontsize=10)
plt.colorbar(CS)

plt.title('My function: $z=(1-x^2+y^2) e^{-(y^3)/3}$')
plt.show()

在这里插入图片描述

示例详解:

numpy 借助少数几个 helper 方法来创建范围和矩阵。
在对 my_function 求值并存储在 Z 之后,简单地调用 contour,并传入 Z 和等值线水平数量。
此时,可以尝试用 arange() 调用中的第三个参数做个实验。例如,尝试将 N = np.arange(-1, 1.5, 0.3) 的参数做一些修改,将值 0.3 改为 0.1 或 1,来体验一下对相同数据进行不同编码时,它在等高线图中呈现的差异。
此外,我们通过简单地传入一个 csmatplotlib.contour.Quadcontourset 实例)向图表添加了一个颜色映射表。


填充图表底层区域

基础知识

  • matplotlib 中绘制一个填充多边形的基本方式是使用 matplotlib.pyplot.fill
    该方法接受和 matplotlib.pyplot.plot 相似的参数,即多个 x、y 对和其他 Line2D 属性。函数返回被添加的 Patch 实例的列表。
  • 除了如 histogram() 等固有的绘制闭合的填充多边形的绘图函数之外,matplotlib 还提供了几个方法来帮助我们绘制填充的图形。
    我们已经提到了一个 matplotlib.pyplot.fill,另外还有 matplotlib.pyplot.fill_between()matplotlib.pyplot.fill_betweenx() 函数。
    这些方法填充两条曲线间的多边形。fill_between()fill_betweenx() 主要的区别是后者填充 x 轴的值之间的区域,而前者填充 y 轴的值之间的区域。

示例

示例1
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt

t = range(1000)
y = [sqrt(i) for i in t]
plt.plot(t, y, color='red', lw=2)
plt.fill_between(t, y, color='silver')
plt.show()

在这里插入图片描述
fill_between()绘制了颜色(‘sliver’)的多边形区域,plot()绘制实际的函数线条。

示例2
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0.0, 2, 0.01)
y1 = np.sin(np.pi*x)
y2 = 1.7*np.sin(4*np.pi*x)

figsize = 15
fig = plt.figure()
fig = plt.figure(figsize=(figsize,figsize))
# 设置标题大小
plt.rcParams.update({'font.size': 16})

axes1 = fig.add_subplot(211)
axes1.plot(x, y1, x, y2, color='grey')
axes1.fill_between(x, y1, y2, where=y2<=y1, facecolor='blue', interpolate=True)
axes1.fill_between(x, y1, y2, where=y2>=y1, facecolor='gold', interpolate=True)
axes1.set_title('Blue where y2 <= y1. Gold-color where y2 >= y1.')
axes1.set_ylim(-2,2)

# 设置图 1 刻度字体大小
plt.tick_params(labelsize=16)

# 屏蔽 y2 中大于 1.0 的值
y2 = np.ma.masked_greater(y2, 1.0)
axes2 = fig.add_subplot(212, sharex=axes1)
axes2.plot(x, y1, x, y2, color='black')
axes2.fill_between(x, y1, y2, where=y2<=y1, facecolor='blue', interpolate=True)
axes2.fill_between(x, y1, y2, where=y2>=y1, facecolor='gold', interpolate=True)
axes2.set_title('Same as above, but mask')
axes2.set_ylim(-2,2)
axes2.grid('on')

# 设置图 2 刻度字体大小
plt.tick_params(labelsize=16)
plt.show()

在这里插入图片描述在这里插入图片描述

示例2工作原理

  • 首先创建了两个在某些点重叠的正弦曲线函数。
    还创建了两个子区,用来比较两种渲染填充区域方式的差异。
  • 使用了带参数 where 的 fill_between() 方法填充 where 等于 True 的区域,其中 where 参数接收一个长度为 N 的布尔数组。
    下面的一个子区演示了 mask_greater,它屏蔽了数组中大于给定值的所有值。
    这是一个 numpy.ma 包中的方法,用来处理缺失或者无效的值。

绘制极线图

基础知识

  • 极线图通常被用来显示本质上是射线的信息。

  • 在极坐标系统中,点被描述为半径距离(通常表示为 r)和角度(通常表示为 theta)。
    角度可以用弧度或者角度表示,但是 matplotlib 使用角度。

  • plot() 函数十分相似的是,我们用 polar() 函数绘制极线图。
    polar() 函数接收两个相同长度的参数数组 thetar,分别用于角度数组和半径数组。
    函数也接收其他和 plot() 函数相同的格式化参数。

  • 我们仍然需要告诉 matplotlib 坐标轴要在极限坐标系统中。
    这通过向 add_axesadd_subplot 提供 polar=True 参数来完成。

  • 为了设置图表中的其他属性,如半径网格或者角度,需要使用 matplotlib.pyplot.rgrids() 来切换半径网格的显示或者设置标签。
    使用 matplotlib.pyplot.thetagrid() 来配置角度刻度和标签。

示例

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt

figsize = 12
colormap = lambda r: cm.Set2(r / 20.) # 用于给不同长度的极线映射不同的颜色
N = 18

fig = plt.figure(figsize=(figsize,figsize)) # 设置 figure 的大小
ax = fig.add_axes([0.2, 0.2, 0.7, 0.7], polar=True) # 设置 axes 的位置和大小

theta = np.arange(0.0, 2 * np.pi, 2 * np.pi/N)  # 随机为极线计算角度
radii = 20 * np.random.rand(N)  # 随机为极线计算长度
width = np.pi / 4 * np.random.rand(N) # 随机为极线计算宽度
bars = ax.bar(theta, radii, width=width, bottom=0.0) # bottom 表示极线的长度从原点开始

for r, bar in zip(radii, bars):
    bar.set_facecolor(colormap(r)) # 给每条极线映射颜色
    bar.set_alpha(0.6) # 设置极线的不透明度

# 设置刻度字体大小
plt.tick_params(labelsize=13)
plt.show()

在这里插入图片描述

工作原理

  • 创建了一个正方形的图表,并向其添加极限坐标轴。
    其实图表不必是正方形的,但是如果不这样的话,极线图就是椭圆形(而不是圆形)的了。

  • 为角度(theta)集合和极线距离(radii)生成随机值。

  • 因为绘制的是极线条,需要为每一个极线条提供宽度集合,因此需要生成一些宽度值。

  • 因为 matplotlib.axes.bar 接收值数组(几乎 matplotlib 中所有的绘图函数都是如此),所以不必在这个生成的数据集合上做循环遍历,只需要调用一次 bar 函数,并传入所有的参数。

  • 为了能够容易区分每一个极线条,需要循环遍历添加到 ax(坐标轴)的每一个极线条,并定制化其外观(表面颜色和透明度)。

补充

figure和axes的关系

 rect = [0.125, 0.125, 0.6, 0.6] 时的结果。
上图为 rect = [0.125, 0.125, 0.6, 0.6] 时的结果。

  • axes 子区域在 figure 区域中,可以通过 fig = plt.figure(figsize=(figsize,figsize)) 来设置 figure 区域的大小。
  • axes 的尺寸、定位是相对于 figure 的。add_axes(rect, projection=None, polar=False, **kwargs) 函数可以用来设置 axes 子区域。
    其中的 rect 是位置参数,接受一个4元素的浮点数列表,[left, bottom, width, height],它定义了要添加到 figure 中的矩形子区域的:左下角坐标 (x, y)、宽度、高度。

注意:每个元素的值是figure宽度和高度的分数。即将figure的宽、高作为1个单位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值