目录
- 前言
- 实现
- 读取数据
- 绘图
- 完整实现
前言
冒个泡泡,好久没有冒泡泡了,那么今天的话就浅浅水一下博文吧。任务是这样的,将Excel当中的数据,把它放到咱们的matlpolitlib里面去画个图。
数据是这样子的:
这里面有很多sheet,然后还有对应的点的坐标。要最终实现的效果就是:
并且我们还需要符合规范:
这样的话图片才不会失真。BOSS不催,小爷不写(狗头)
实现
那么这里的话就是咱们的实现了这个Excel的读取,然后是绘制图片。
读取数据
首先是读取数据,这部分相当简单,就在初始化做了。
def __init__(self,file_path,pic_name=None, | |
legend_names=None,padx=,pady=1, | |
save_path_pre="./pic" | |
): | |
""" | |
默认存储的图片为K,600dpi | |
:param file_path: | |
:param pic_name: | |
:param legend_names: | |
:param padx: | |
:param pady: | |
:param save_path_pre: | |
""" | |
self.xl_file = xlrd.open_workbook(file_path) | |
self.sheet_names = self.xl_file.sheet_names() | |
self.legend_names = None | |
self.setTrans = False | |
self.setFig = False | |
self.join = False | |
self.padx = padx | |
self.pady = pady | |
self.save_path_pre = save_path_pre | |
if(pic_name): | |
self.pic_name = pic_name | |
else: | |
self.pic_name = self.sheet_names | |
if(legend_names and padx==None): | |
self.legend_names=legend_names | |
elif(legend_names==None): | |
sheet = self.xl_file.sheets()[0] | |
sheet_cols = sheet1.col_values(padx) | |
self.legend_names = sheet_cols[pady:] | |
elif(legend_names!=None): | |
self.legend_names = legend_names | |
else: | |
raise Exception("请检查格式,或者参数设置") |
这里我解释一下这几个参数的含义
默认存储的图片为4K,600dpi
:param file_path:
:param pic_name:
:param legend_names: 图例的名字
:param padx: 数据是从哪一个列开始的
:param pady: 哪一个行开始的
:param save_path_pre:
"""
例如刚刚的例子,是在第1行第1列开始的,下标0开始。
如果没有指定那个图例说明的话,那么代码就会直接取pady那一列的数据作为图例。
绘图
这个绘图的话非常简单,就是直接使用那个plt,读取好数据就好了。
def creatPic(self,legend_loc='upper right',multiple=, | |
padding=,width=4096,height=3112 | |
): | |
""" | |
:param legend_loc: 图例的说明 | |
:return: | |
""" | |
if(self.setFig and self.setFig): | |
for sheet_index in range(len(self.xl_file.sheet_names())): | |
sheet = self.xl_file.sheets()[sheet_index] | |
self.plt = self.creatFigure() | |
#按照行进行读取 | |
for row in range(self.pady,len(self.legend_names)+self.pady): | |
row_data_y = [self.transform(float(data),padding) for data in sheet.row_values(row)[self.padx+:]] | |
row_data_x = [x*multiple for x in range(len(row_data_y))] | |
label_name = self.legend_names[row-self.pady] | |
self.plt.plot(row_data_x,row_data_y,label=label_name) | |
plt.legend() | |
save_path = self.save_path_pre+"./"+self.pic_name[sheet_index]+".jpg" | |
self.plt.savefig(save_path, | |
dpi=, bbox_inches='tight' | |
) | |
self.changeImgSiz(save_path) | |
self.plt.pause(.05) | |
else: | |
raise Exception("请先设置数据转换方式以及绘图") |
这里的话还有一点就是有一个修改图片尺寸的代码,以为画布尺寸和那个实际图片尺寸还是有点区别的。这个看着改吧,当然你可以选择保存为png,但是这样的话,x,y轴的说明可能没有了。那么重新resize的话,dpi会变成96,所以看自己吧
完整实现
import matplotlib.pyplot as plt # 为方便简介为plt | |
import xlrd | |
import math | |
from PIL import Image | |
class Draw(object): def __init__(self,file_path,pic_name=None, | |
legend_names=None,padx=,pady=1, | |
save_path_pre="./pic" | |
): | |
""" | |
默认存储的图片为K,600dpi | |
:param file_path: | |
:param pic_name: | |
:param legend_names: | |
:param padx: | |
:param pady: | |
:param save_path_pre: | |
""" | |
self.xl_file = xlrd.open_workbook(file_path) | |
self.sheet_names = self.xl_file.sheet_names() | |
self.legend_names = None | |
self.setTrans = False | |
self.setFig = False | |
self.join = False | |
self.padx = padx | |
self.pady = pady | |
self.save_path_pre = save_path_pre | |
if(pic_name): | |
self.pic_name = pic_name | |
else: | |
self.pic_name = self.sheet_names | |
if(legend_names and padx==None): | |
self.legend_names=legend_names | |
elif(legend_names==None): | |
sheet = self.xl_file.sheets()[0] | |
sheet_cols = sheet1.col_values(padx) | |
self.legend_names = sheet_cols[pady:] | |
elif(legend_names!=None): | |
self.legend_names = legend_names | |
else: | |
raise Exception("请检查格式,或者参数设置") | |
def setTransform(self,joinPoint=None): | |
if(joinPoint): | |
self.transform = joinPoint | |
self.join = True | |
else: | |
self.transform_core = math.log | |
self.setTrans = True | |
def transform(self,x,pading=): | |
if(self.join): | |
return self.transform_core(x) | |
else: | |
return self.transform_core(x+pading) | |
def setFigure(self,style='seaborn-whitegrid',fig=None, | |
xlabel='x',ylabel='log(y)'): | |
self.fig = fig | |
self.style = style | |
self.xlabel = xlabel | |
self.ylabel = ylabel | |
self.setFig = True | |
def changeImgSiz(self,path,width=,height=4096): | |
img_switch = Image.open(path) | |
img_deal = img_switch.resize((width,height), Image.ANTIALIAS) | |
img_deal.save(path) | |
def creatFigure(self): | |
self.plt = plt | |
if(self.fig): | |
self.plt = self.fig() | |
else: | |
self.plt.rcParams['font.sans-serif'] = ['SimHei'] | |
self.plt.rcParams['axes.unicode_minus'] = False | |
self.plt.figure(figsize=(, 8)) | |
self.plt.style.use(self.style) | |
self.plt.xlabel(self.xlabel) | |
self.plt.ylabel(self.ylabel) | |
return self.plt | |
def creatPic(self,legend_loc='upper right',multiple=, | |
padding=,width=4096,height=3112 | |
): | |
""" | |
:param legend_loc: 图例的说明 | |
:return: | |
""" | |
if(self.setFig and self.setFig): | |
for sheet_index in range(len(self.xl_file.sheet_names())): | |
sheet = self.xl_file.sheets()[sheet_index] | |
self.plt = self.creatFigure() | |
#按照行进行读取 | |
for row in range(self.pady,len(self.legend_names)+self.pady): | |
row_data_y = [self.transform(float(data),padding) for data in sheet.row_values(row)[self.padx+:]] | |
row_data_x = [x*multiple for x in range(len(row_data_y))] | |
label_name = self.legend_names[row-self.pady] | |
self.plt.plot(row_data_x,row_data_y,label=label_name) | |
plt.legend() | |
save_path = self.save_path_pre+"./"+self.pic_name[sheet_index]+".jpg" | |
self.plt.savefig(save_path, | |
dpi=, bbox_inches='tight' | |
) | |
self.changeImgSiz(save_path) | |
self.plt.pause(.05) | |
else: | |
raise Exception("请先设置数据转换方式以及绘图") | |
if __name__ == '__main__': file_path = '' | |
save_path_pre = '' | |
legend_names = ['','',''] | |
draw = Draw(file_path,legend_names=legend_names,save_path_pre=save_path_pre) | |
draw.setTransform() | |
draw.setFigure() | |
draw.creatPic() |