使用python将作图并将局部放大

此程序主要特点:

1、使用python画实验结果图

2、想要对大图的局部进行放大

3、有两个子图

4、子图和原图的横坐标都使用标签而不是原始的数据

代码和注释如下:


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import openpyxl as xl
from mpl_toolkits.axes_grid1.inset_locator import mark_inset

excel_file  = xl.load_workbook('D:\Hnu\Project5 CP\实验结果\\baseline选择.xlsx')
sheet_name = 'Scalability'  #对应的sheet的名称
sheet = excel_file[sheet_name] # 定位excel中具体的表单
data = pd.DataFrame(sheet.values)# 提取表单中的具体数据所在的行和列
selected_data = data.iloc[23:28,1:11]
print(selected_data)
fig, ax = plt.subplots(figsize=(9, 8))#用来控制图片的大小
#设定图片中文字和标签大小的参数
fontsize = 12

# 绘制柱状图,正常坐标,第一个参数是横坐标
# 第二参数,是纵坐标数据,注意11,12,13是列名,是从excel读来的绝对列名,不是selected_data的相对列数
ax.plot(selected_data.iloc[:,0], selected_data[2],marker='o', label='order=4,dim=100')
ax.plot(selected_data.iloc[:,0], selected_data[3],marker='v', label='order=4,dim=1000')
ax.plot(selected_data.iloc[:,0], selected_data[4],marker='d',label='order=3,dim=1000')
ax.plot(selected_data.iloc[:,0], selected_data[5],marker='*',label='order=5,dim=100')
ax.plot(selected_data.iloc[:,0], selected_data[6],marker='s',label='order=5,dim=1000')
ax.plot(selected_data.iloc[:,0], selected_data[7],marker='^',label='order=6,dim=100')
ax.plot(selected_data.iloc[:,0], selected_data[8],marker='h',label='order=6,dim=1000')
ax.plot(selected_data.iloc[:,0], selected_data[9],marker='x',label='order=7,dim=100')
ax.plot(selected_data.iloc[:,0], selected_data[10],marker='+',label='order=7,dim=1000')
#ax.plot(selected_data.iloc[:,1], selected_data[4],color='blue',marker='p',label='GTA')
#ax.plot(selected_data.iloc[:,0], selected_data[5],color='red',marker='*',label='CL_tucker')

#ax.set_yscale('log', basey=10)#设置柱子的纵坐标为对数刻度
#ax.set_yscale('log')#设置柱子的纵坐标为对数刻度

#plt.text(6+1.2,selected_data.iloc[4,5]-0.2, 'A ({:.1f}X)'.format(selected_data.iloc[4,5]), fontsize = 12,ha = 'center')
#plt.text(6+0.3,selected_data.iloc[4,2]+0.4, 'B({:.1f}X)'.format(selected_data.iloc[4,2]), fontsize = 12,ha = 'center')
#plt.text(3,selected_data.iloc[2,1]+0.5, '{:.1f}x'.format(selected_data.iloc[2,3]/selected_data.iloc[2,1]), fontsize = 7,ha = 'center')
#plt.text(4-0.1,selected_data.iloc[3,1]+2, '{:.1f}x'.format(selected_data.iloc[3,3]/selected_data.iloc[3,1]), fontsize = 7,ha = 'center')
#plt.text(5-0.1,selected_data.iloc[4,1]+10, '{:.1f}x'.format(selected_data.iloc[4,3]/selected_data.iloc[4,1]), fontsize = 7,ha = 'center')

# 设置图表标题和轴标题
#plt.title('N = 4 , I_n = 1000')
#plt.title('Enron',fontsize = 12)
plt.xlabel('The number of nonzeros of the input tensor',fontsize=12)
plt.ylabel('Fit',fontsize=12)

# 设置图例
plt.legend(loc='best', ncol=1,fontsize=12)#设置图例的位置和列数

#横坐标为作图数据的时候,设置横纵坐标的显示范围,和刻度间隔
#ax.set_xlim([0.08, 10.5]) #设置坐标显示范围
#xtick_interval = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]#设置刻度间隔
#ax.set_xticks(ticks=xtick_interval)
#ax.set_ylim([0.5, 1.4]) #设置坐标显示范围

#横坐标的刻度不显示作图所用的数据的时候,可以配合plt.xticks显示此处设置的标签
labels = ['1K','10K','100K','1M','10M']
positions = selected_data.iloc[:,0].tolist()
plt.xticks(positions , labels,fontsize = fontsize)  #使得标签现实的是给定的文字标签

#plt.xticks(x, fontsize=12, rotation=45,loc='inside')#设置标签的文字大小和旋转方向
plt.yticks(fontsize= fontsize)


#以下代码是为了绘制局部放大图
#第一步,嵌入绘制局部放大图的坐标系
axins = ax.inset_axes((0.08, 0.05, 0.25, 0.25))
#上述代码的含义是:以父坐标系中的x0=0.2x,y0=0.2y为左下角起点,嵌入一个宽度为0.4x,高度为0.3y的子坐标系,其中x和y分别为父坐标系的坐标轴范围。
axins.plot(selected_data.iloc[:,0], selected_data[2],marker='o', label='order=4,dim=100')
axins.plot(selected_data.iloc[:,0], selected_data[3],marker='v', label='order=4,dim=1000')
axins.plot(selected_data.iloc[:,0], selected_data[4],marker='d',label='order=3,dim=1000')
axins.plot(selected_data.iloc[:,0], selected_data[5],marker='*',label='order=5,dim=100')
axins.plot(selected_data.iloc[:,0], selected_data[6],marker='s',label='order=5,dim=1000')
axins.plot(selected_data.iloc[:,0], selected_data[7],marker='^',label='order=6,dim=100')
axins.plot(selected_data.iloc[:,0], selected_data[8],marker='h',label='order=6,dim=1000')
axins.plot(selected_data.iloc[:,0], selected_data[9],marker='x',label='order=7,dim=100')
axins.plot(selected_data.iloc[:,0], selected_data[10],marker='+',label='order=7,dim=1000')
#设置局部放大后的显示范围
x_ratio = 0.3  # x轴显示范围的扩展比例
y_ratio = 0.6  # y轴显示范围的扩展比例
#设置x轴的显示范围
xlim0 = selected_data.iloc[:,0][25] - 0.2
xlim1 = selected_data.iloc[:,0][25] + 0.2
#这里的25来源于我们从excel种读取数据后,python人认为我们读取的是1到11列,23到28行
#而25行就是我们图中的横坐标方向上的第三个数据值(1K,10K,100K),就是我们想要放大的数据的横坐标的坐标值
#设置Y轴的显示范围
y = np.hstack((selected_data.iloc[2,1],selected_data.iloc[2,4],selected_data.iloc[2,6],selected_data.iloc[2,8]))
#我们想要放大的四个数据(原始数据的纵坐标值)的组成一个数组,找出其中最大的和最小的,进行纵坐标范围的确定
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=4, loc2=1, fc="none", ec='gray', lw=1.5,linestyle='--')

axins_labels = ['10K','100K','1M']#设置刻度标签,不设置默认显示的是(xlim0, xlim1)之间的数字
axins.set_xticks([xlim0,(xlim0+xlim1)/2,xlim1])  # 设置刻度位置
axins.set_xticklabels(axins_labels)  # 在对应的刻度位置上打上对应的标签

#画第二个子图
axins1 = ax.inset_axes((0.77, 0.2, 0.2, 0.38))
#上述代码的含义是:以父坐标系中的x0=0.2x,y0=0.2y为左下角起点,嵌入一个宽度为0.4x,高度为0.3y的子坐标系,其中x和y分别为父坐标系的坐标轴范围。
axins1.plot(selected_data.iloc[:,0], selected_data[2],marker='o', label='order=4,dim=100')
axins1.plot(selected_data.iloc[:,0], selected_data[3],marker='v', label='order=4,dim=1000')
axins1.plot(selected_data.iloc[:,0], selected_data[4],marker='d',label='order=3,dim=1000')
axins1.plot(selected_data.iloc[:,0], selected_data[5],marker='*',label='order=5,dim=100')
axins1.plot(selected_data.iloc[:,0], selected_data[6],marker='s',label='order=5,dim=1000')
axins1.plot(selected_data.iloc[:,0], selected_data[7],marker='^',label='order=6,dim=100')
axins1.plot(selected_data.iloc[:,0], selected_data[8],marker='h',label='order=6,dim=1000')
axins1.plot(selected_data.iloc[:,0], selected_data[9],marker='x',label='order=7,dim=100')
axins1.plot(selected_data.iloc[:,0], selected_data[10],marker='+',label='order=7,dim=1000')
#设置局部放大后的显示范围
x_ratio = 0.3  # x轴显示范围的扩展比例
y_ratio = 0.02  # y轴显示范围的扩展比例
#设置x轴的显示范围
xlim00 = selected_data.iloc[:,0][26] - 0.2
xlim10 = selected_data.iloc[:,0][26] + 0.2
#这里的25来源于我们从excel种读取数据后,python人认为我们读取的是1到11列,23到28行
#而25行就是我们图中的横坐标方向上的第四个数据值(1K,10K,100K,1M),就是我们想要放大的数据的横坐标的坐标值
#设置Y轴的显示范围
y1 = np.hstack((selected_data.iloc[3,1],selected_data.iloc[3,2],selected_data.iloc[3,3],selected_data.iloc[3,4],selected_data.iloc[3,5],selected_data.iloc[3,6],selected_data.iloc[3,7],selected_data.iloc[3,8],selected_data.iloc[3,9]))
#我们想要放大的四个数据(原始数据的纵坐标值)的组成一个数组,找出其中最大的和最小的,进行纵坐标范围的确定
ylim00 = np.min(y1) - (np.max(y1) - np.min(y1)) * y_ratio-0.001
ylim10 = np.max(y1) + (np.max(y1) - np.min(y1)) * y_ratio+0.001
# 调整子坐标系的显示范围
axins1.set_xlim(xlim00, xlim10)
axins1.set_ylim(ylim00, ylim10)
# 建立父坐标系与子坐标系的连接线
# loc1 loc2: 坐标系的四个角
# 1 (右上) 2 (左上) 3(左下) 4(右下)
mark_inset(ax, axins1, loc1=2, loc2=4, fc="none", ec='gray', lw=1.5,linestyle='--')

axins1_labels = ['100K','1M','10M']#设置刻度标签,不设置默认显示的是(xlim0, xlim1)之间的数字
axins1.set_xticks([xlim00,(xlim00+xlim10)/2,xlim10])  # 设置刻度位置
axins1.set_xticklabels(axins1_labels)  # 在对应的刻度位置上打上对应的标签



#保存和显示图片,必须先保存,后显示图片
plt.savefig('Scalability_NNZ_Fit.png',dpi=300,bbox_inches='tight')
plt.show()

最终效果:

### 实现Python图片局部放大的方法 为了实现图像的局部放大效果,可以采用多种方式来完成这一目标。一种常见的方式是利用`matplotlib`库绘制带有插图(即局部放大部分)的整体图形[^1]。 #### 使用Matplotlib创建带局部放大的图表 下面是一段简单的例子,展示了怎样通过五条语句构建一个具有嵌入式子图(用来表示被放大的细节部分)的画面: ```python import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes, mark_inset import numpy as np def plot_with_zoom(image_path): fig, ax = plt.subplots() # 加载显示原图 img = plt.imread(image_path) ax.imshow(img) # 创建缩放窗口 axins = zoomed_inset_axes(ax, 2, loc='upper right') # 放大倍数为2倍,在右上角位置 extent = (0.45*img.shape[1], 0.55*img.shape[1]), (0.45*img.shape[0], 0.55*img.shape[0]) axins.imshow(img, extent=[*extent[0], *extent[1]]) # 设置放大区域边界框以及连接线样式 mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="blue") plot_with_zoom('dog.jpg') plt.show() ``` 此代码片段首先加载了一张名为'dog.jpg'的照片作为背景,在其基础上添加了一个位于右上方的小视窗专门用于呈现选定区域内经过放大的景象;同时还在两者之间画出了指示性的线条以便于观察者理解它们之间的对应关系[^3]。 对于更复杂的场景下可能涉及到多个不同位置的同时放大或是其他自定义需求,则可以根据实际情况调整上述模板中的参数设置或引入额外的功能模块来进行扩展[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值