在作对比实验中,除了对总体形状的对比,在不少状况下都须要对某一局部的数据进行放大,来观察更加精细的对比效果。算法
工具数组
Python的Matplotlib库函数网络
步骤
一、导入依赖库app
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1.inset_locator import inset_axes from matplotlib.patches import ConnectionPatch
二、准备数据框架
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算法中设置的不一样的学习率:工具
三、绘主图post
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为列数。学习
效果图以下:
四、嵌入局部放大图的坐标系
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.2x,高度为0.3y的子坐标系,其中x和y分别为父坐标系的坐标轴范围。效果以下图所示:
五、在子坐标系中绘制原始数据
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}$')
效果以下:
六、设置放大区间,调整子坐标系的显示范围
# 设置放大区间 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)
效果以下:
七、创建父坐标系与子坐标系的链接线
# 原图中画方框 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)
最后将链接线添加进子图。注意是子图不是主图。
效果图以下:
以上就是局部放大图的画法,最后的方框和线的画法不止一种,这里只是找了比较简单直接的一种。 但愿对你有帮助。
原文连接: https://juejin.im/post/5eddf7a96fb9a047923a483b
文源网络,仅供学习之用,若有侵权请联系删除。
在学习Python的道路上确定会碰见困难,别慌,我这里有一套学习资料,包含40+本电子书,800+个教学视频,涉及Python基础、爬虫、框架、数据分析、机器学习等,不怕你学不会! https://shimo.im/docs/JWCghr8prjCVCxxK/ 《Python学习资料》
关注公众号【Python圈子】,优质文章每日送达。