Preface
In data visualization, it is often necessary to partially enlarge the data in a certain interval to obtain a higher contrast visualization effect. The following uses the Matplotlib library of the Python language to implement a simple partial magnification effect.
Dependent libraries
matplotlib: drawing library
numpy: an extension library that supports a large number of dimensional arrays, matrix operations and mathematical functions
step
- Import dependent libraries
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
- Prepare data
x = np.linspace(-0.1*np.pi, 2*np.pi, 30)
y_1 = np.sinc(x)+0.7
y_2 = np.tanh(x)
y_3 = np.exp(-np.sinc(x))
- Drawing
fig, ax = plt.subplots(1, 1, figsize=(6, 4))
ax.plot(x, y_1, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C0')
ax.plot(x, y_2, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C3')
ax.plot(x, y_3, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C2')
ax.legend(labels=["y_1", "y_2","y_3"], ncol=3)
The renderings are as follows:
- Embed the coordinate system for drawing partial magnification
axins = inset_axes(ax, width="40%", height="30%", loc='lower left',
bbox_to_anchor=(0.1, 0.1, 1, 1),
bbox_transform=ax.transAxes)
Parameter Description
ax: Parent coordinate system
width, height: Width and height of child coordinate system (percentage form or floating point number)
loc: The position of the sub-coordinate system
bbox_to_anchor: Bounding box, quad array (x0, y0, width, height)
bbox_transform: Geometric mapping from parent coordinate system to child coordinate system a>
axins: sub-coordinate system
Fixed the width and height of the coordinate system and the bounding box, and set loc to the upper left, lower left, and upper right respectively (Default), lower right and middle, the rendering is as follows:
For detailed usage instructions on mpl_toolkits.axes_grid1.inset_locator.inset_axes, please refer to the official documentation
https://matplotlib.org/3.2.1/api/_as_gen/mpl_toolkits.axes_grid1.inset_locator.inset_axes.html
In this example, embed the subcoordinate system at the appropriate location:
axins = inset_axes(ax, width="40%", height="30%", loc='lower left',
bbox_to_anchor=(0.5, 0.1, 1, 1),
bbox_transform=ax.transAxes)
The renderings are as follows:
There is also a simpler sub-coordinate system embedding method:——Recommended
axins = ax.inset_axes((0.2, 0.2, 0.4, 0.3))
ax is the parent coordinate system, and the following four parameters are also (x0, y0, width, height). The meaning of the above code is: x0=0.2 in the parent coordinate systemx, y0=0.2y is the starting point of the lower left corner, embedded with a width of 0.4x and a height of 0.3y The child coordinate system of , where x and y are the coordinate axis ranges of the parent coordinate system respectively. The effect is as shown below:
- Plot original data in subcoordinate system
axins.plot(x, y_1, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C0')
axins.plot(x, y_2, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C3')
axins.plot(x, y_3, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C2')
The renderings are as follows:
- Set the magnification interval and adjust the display range of the sub-coordinate system
# 设置放大区间
zone_left = 11
zone_right = 12
# 坐标轴的扩展比例(根据实际数据调整)
x_ratio = 0.5 # x轴显示范围的扩展比例
y_ratio = 0.5 # y轴显示范围的扩展比例
# X轴的显示范围
xlim0 = x[zone_left]-(x[zone_right]-x[zone_left])*x_ratio
xlim1 = x[zone_right]+(x[zone_right]-x[zone_left])*x_ratio
# Y轴的显示范围
y = np.hstack((y_1[zone_left:zone_right], y_2[zone_left:zone_right], y_3[zone_left:zone_right]))
ylim0 = np.min(y)-(np.max(y)-np.min(y))*y_ratio
ylim1 = np.max(y)+(np.max(y)-np.min(y))*y_ratio
# 调整子坐标系的显示范围
axins.set_xlim(xlim0, xlim1)
axins.set_ylim(ylim0, ylim1)
The renderings are as follows:
- Establish a connection line between the parent coordinate system and the child coordinate system
# loc1 loc2: 坐标系的四个角
# 1 (右上) 2 (左上) 3(左下) 4(右下)
mark_inset(ax, axins, loc1=3, loc2=1, fc="none", ec='k', lw=1)
loc1 and loc2 are the four corners of the parent coordinate system and the child coordinate system respectively, and their values are 1, 2, 3, and 4. The corresponding four corners are: upper right, upper left, lower left, and lower right. Taking loc1=3, loc2=1 as an example, the implemented function is: the lower left corner of the parent coordinate system is connected to the lower left corner of the child coordinate system, and the upper right corner of the parent coordinate system is connected to the upper right corner of the child coordinate system. The renderings are as follows:
The above is an example of using Matplotlib to implement the local enlargement drawing method. The key lies in the setting of the bbox_to_anchor parameter. Using this parameter, the coordinate system embedding at any position can be achieved.
The complete code is as follows:
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
# 准备数据
x = np.linspace(-0.1*np.pi, 2*np.pi, 30)
y_1 = np.sinc(x)+0.7
y_2 = np.tanh(x)
y_3 = np.exp(-np.sinc(x))
# 绘图
fig, ax = plt.subplots(1, 1, figsize=(6, 4))
ax.plot(x, y_1, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C0')
ax.plot(x, y_2, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C3')
ax.plot(x, y_3, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C2')
ax.legend(labels=["y_1", "y_2","y_3"], ncol=3)
# 嵌入绘制局部放大图的坐标系
axins = inset_axes(ax, width="40%", height="30%",loc='lower left',
bbox_to_anchor=(0.5, 0.1, 1, 1),
bbox_transform=ax.transAxes)
# 在子坐标系中绘制原始数据
axins.plot(x, y_1, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C0')
axins.plot(x, y_2, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C3')
axins.plot(x, y_3, color='k', linestyle=':', linewidth=1,
marker='o', markersize=5,
markeredgecolor='black', markerfacecolor='C2')
# 设置放大区间
zone_left = 11
zone_right = 12
# 坐标轴的扩展比例(根据实际数据调整)
x_ratio = 0.5 # x轴显示范围的扩展比例
y_ratio = 0.5 # y轴显示范围的扩展比例
# X轴的显示范围
xlim0 = x[zone_left]-(x[zone_right]-x[zone_left])*x_ratio
xlim1 = x[zone_right]+(x[zone_right]-x[zone_left])*x_ratio
# Y轴的显示范围
y = np.hstack((y_1[zone_left:zone_right], y_2[zone_left:zone_right], y_3[zone_left:zone_right]))
ylim0 = np.min(y)-(np.max(y)-np.min(y))*y_ratio
ylim1 = np.max(y)+(np.max(y)-np.min(y))*y_ratio
# 调整子坐标系的显示范围
axins.set_xlim(xlim0, xlim1)
axins.set_ylim(ylim0, ylim1)
# 建立父坐标系与子坐标系的连接线
# loc1 loc2: 坐标系的四个角
# 1 (右上) 2 (左上) 3(左下) 4(右下)
mark_inset(ax, axins, loc1=3, loc2=1, fc="none", ec='k', lw=1)
# 显示
plt.show()