[Data processing] python Matplotlib partially enlarges the figure; marks the local enlarged subfigure of interest

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

  1. 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
  1. 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))
  1. 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:

Insert image description here

  1. 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:
Insert image description here

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:

Insert image description here

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:
Insert image description here

  1. 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:Insert image description here

  1. 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:
Insert image description here

  1. 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:

Insert image description here
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()

Guess you like

Origin blog.csdn.net/weixin_39589455/article/details/134402805