pythonmatplotlib画法_【Python】Matplotlib局部放大图画法

前言

在做对比实验中,除了对整体形状的对比,在很多情况下都需要对某一局部的数据进行放大,来观察更加精细的对比效果。

工具

Python的Matplotlib库函数

步骤

1.导入依赖库

import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1.inset_locator import inset_axes

from matplotlib.patches import ConnectionPatch

复制代码

2.准备数据

reward_demaddpg[]储存的是执行demaddpg算法后所获得的300个reward结果。

因此横坐标设置为:

MAX_EPISODES = 300

x_axis_data = []

for l in range(MAX_EPISODES):

x_axis_data.append(l)

复制代码

5个对比实验结果存在5个数组中,分别表示demaddpg算法中设置的不同的学习率:

reward_demaddpg5[]:learning rate=

reward_demaddpg10[]:learning rate=

reward_demaddpg15[]:learning rate=

reward_demaddpg20[]:learning rate=

reward_demaddpg25[]:learning rate=

3.绘主图

fig, ax = plt.subplots(1, 1)

ax.plot(x_axis_data, reward_demaddpg5, color='#4169E1', alpha=0.8, label='$1*10^{-5}$')

ax.plot(x_axis_data, reward_demaddpg10, color='#848484', alpha=0.8, label='$5*10^{-6}$')

ax.plot(x_axis_data, reward_demaddpg15, color='#FF774A', alpha=0.8, label='$1*10^{-6}$')

ax.plot(x_axis_data, reward_demaddpg20, color='#575B20', alpha=0.8, label='$5*10^{-7}$')

ax.plot(x_axis_data, reward_demaddpg25, color='#B84D37', alpha=0.8, label='$1*10^{-7}$')

ax.legend(loc="lower right")

ax.set_xlabel('Episodes')

ax.set_ylabel('Total reward')

复制代码

其中fig, ax = plt.subplots(a,b)用来控制子图个数:a为行数,b为列数。

效果图如下:

4.嵌入局部放大图的坐标系

axins = inset_axes(ax, width="40%", height="30%", loc='lower left',

bbox_to_anchor=(0.3, 0.1, 1, 1),

bbox_transform=ax.transAxes)

复制代码

参数解释如下:

ax:父坐标系

width, height:子坐标系的宽度和高度(百分比形式或者浮点数个数)

loc:子坐标系的位置

bbox_to_anchor:边界框,四元数组(x0, y0, width, height)

bbox_transform:从父坐标系到子坐标系的几何映射

axins:子坐标系

固定坐标系的宽度和高度以及边界框,分别设置loc为左上、左下、右上(默认)、右下和中间,效果图如下:

效果图如下:

另外有一种更加简洁的子坐标系嵌入方法:

axins = ax.inset_axes((0.2, 0.2, 0.4, 0.3))

复制代码

ax为父坐标系,后面四个参数同样是(x0, y0, width, height),上述代码的含义是:以父坐标系中的x0=0.2*x,y0=0.2*y为左下角起点,嵌入一个宽度为0.2*x,高度为0.3*y的子坐标系,其中x和y分别为父坐标系的坐标轴范围。效果如下图所示:

5.在子坐标系中绘制原始数据

axins.plot(x_axis_data, reward_demaddpg5, color='#4169E1', alpha=0.8, label='$1*10^{-5}$')

axins.plot(x_axis_data, reward_demaddpg10, color='#848484', alpha=0.8, label='$5*10^{-6}$')

axins.plot(x_axis_data, reward_demaddpg15, color='#FF774A', alpha=0.8, label='$1*10^{-6}$')

axins.plot(x_axis_data, reward_demaddpg20, color='#575B20', alpha=0.8, label='$5*10^{-7}$')

axins.plot(x_axis_data, reward_demaddpg25, color='#B84D37', alpha=0.8, label='$1*10^{-7}$')

复制代码

效果如下:

6.设置放大区间,调整子坐标系的显示范围

# 设置放大区间

zone_left = 100

zone_right = 150

# 坐标轴的扩展比例(根据实际数据调整)

x_ratio = 0 # x轴显示范围的扩展比例

y_ratio = 0.05 # y轴显示范围的扩展比例

# X轴的显示范围

xlim0 = x_axis_data[zone_left]-(x_axis_data[zone_right]-x_axis_data[zone_left])*x_ratio

xlim1 = x_axis_data[zone_right]+(x_axis_data[zone_right]-x_axis_data[zone_left])*x_ratio

# Y轴的显示范围

y = np.hstack((reward_demaddpg5[zone_left:zone_right], reward_demaddpg10[zone_left:zone_right],

reward_demaddpg15[zone_left:zone_right],reward_demaddpg20[zone_left:zone_right],

reward_demaddpg25[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)

复制代码

效果如下:

7. 建立父坐标系与子坐标系的连接线

# 原图中画方框

tx0 = xlim0

tx1 = xlim1

ty0 = ylim0

ty1 = ylim1

sx = [tx0,tx1,tx1,tx0,tx0]

sy = [ty0,ty0,ty1,ty1,ty0]

ax.plot(sx,sy,"black")

# 画两条线

xy = (xlim0,ylim0)

xy2 = (xlim0,ylim1)

con = ConnectionPatch(xyA=xy2,xyB=xy,coordsA="data",coordsB="data",

axesA=axins,axesB=ax)

axins.add_artist(con)

xy = (xlim1,ylim0)

xy2 = (xlim1,ylim1)

con = ConnectionPatch(xyA=xy2,xyB=xy,coordsA="data",coordsB="data",

axesA=axins,axesB=ax)

axins.add_artist(con)

复制代码

画方框

使用了画连接方框四个顶点的四条线段就可以了,从某个点绕个圈再回到起点,就画出了方框,使用pyplot(x,y),还可以方便地指定颜色,线宽等。

画跨子图的线

这里使用连接线,在matplotlib.patches有一个ConnectionPatch类型,就是用的这个,它可以用在一个或多个子图之间画线。

con = ConnectionPatch(xyA,xyB,coordsA,coordsB, axesA,axesB)

这里xyA是子图里面的点,xyB是主图里面的点,coordsA和coordsB默认值"data",也不用改,然后就是axesA要添加子图,axesB为要连接的主图。

axins.add_artist(con)

最后将连接线添加进子图。注意是子图不是主图。

效果图如下:

小结

以上就是局部放大图的画法,最后的方框和线的画法不止一种,这里只是找了比较简单直接的一种。

希望对你有帮助。

具体数据由于来自未发表的论文,所以不方便公布。

你可能感兴趣的:(pythonmatplotlib画法_【Python】Matplotlib局部放大图画法)