python绘图小dome

54 阅读3分钟

前言

冒个泡泡,好久没有冒泡泡了,那么今天的话就浅浅水一下博文吧。任务是这样的,将Excel当中的数据,把它放到咱们的matlpolitlib里面去画个图。 数据是这样子的: 在这里插入图片描述 这里面有很多sheet,然后还有对应的点的坐标。要最终实现的效果就是: 在这里插入图片描述 并且我们还需要符合规范: 在这里插入图片描述 这样的话图片才不会失真。BOSS不催,小爷不写(狗头)

实现

那么这里的话就是咱们的实现了这个Excel的读取,然后是绘制图片。

读取数据

首先是读取数据,这部分相当简单,就在初始化做了。

    def __init__(self,file_path,pic_name=None,
                 legend_names=None,padx=0,pady=1,
                 save_path_pre="./pic"
                 ):

        """
        默认存储的图片为4K,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):
            sheet1 = self.xl_file.sheets()[0]
            sheet1_cols = sheet1.col_values(padx)
            self.legend_names = sheet1_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=40,
                 padding=10000,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+1:]]
                    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=600, bbox_inches='tight'
                                 )
                self.changeImgSiz(save_path)
                self.plt.pause(0.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=0,pady=1,
                 save_path_pre="./pic"
                 ):

        """
        默认存储的图片为4K,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):
            sheet1 = self.xl_file.sheets()[0]
            sheet1_cols = sheet1.col_values(padx)
            self.legend_names = sheet1_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=10000):
        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=4096,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, 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=40,
                 padding=10000,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+1:]]
                    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=600, bbox_inches='tight'
                                 )
                self.changeImgSiz(save_path)
                self.plt.pause(0.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()

总结

ok,水完了,快结束了