Python中局部放大图案例
例子一:
先上完整代码和效果图:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from matplotlib.patches import ConnectionPatch
MAX_EPISODES = 10000
x_axis_data = []
for l in range(MAX_EPISODES):
x_axis_data.append(l)
reward_demaddpg5=[]
reward_demaddpg10=[]
for l in range(MAX_EPISODES):
reward_demaddpg5.append(l**1.5)
for l in range(MAX_EPISODES):
reward_demaddpg10.append(l**1.6)
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="best")
ax.set_xlabel('Episodes')
ax.set_ylabel('Total reward')
# axins = inset_axes(ax, width="40%", height="30%", loc='lower left',
# bbox_to_anchor=(0.3, 0.1, 1, 1),
# bbox_transform=ax.transAxes)
axins = ax.inset_axes((0.2, 0.5, 0.4, 0.3))
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}$')
# 设置放大区间 对应横坐标
zone_left = 9000
zone_right =9999 #!最右侧不能越界!!!!
# 坐标轴的扩展比例(根据实际数据调整)
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],
))
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)
plt.show()
导入库:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from matplotlib.patches import ConnectionPatch
横坐标设置:
MAX_EPISODES = 300 #自己定
x_axis_data = []
for l in range(MAX_EPISODES):
x_axis_data.append(l)
#reward_demaddpg[]储存的是执行demaddpg算法后所获得的结果。
其中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:子坐标系
另外有一种更加简洁的子坐标系嵌入方法:更好理解
axins = ax.inset_axes((0.2, 0.2, 0.4, 0.3))
设置放大区间,调整子坐标系的显示范围
# 设置放大区间
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)
参考链接:Python中 Matplotlib局部放大图的画法_wulishinian的博客-CSDN博客_python 局部放大
方案二:
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()