Python绘图系统26:坐标和绘图函数设置

文章目录

    • 封装绘图函数
    • 绘图系统简单的修改
    • 源代码

Python绘图系统:

  • 前置源码: Python打造动态绘图系统
  • 一 三维绘图系统 二 多图绘制系统三 坐 标 轴 定 制
  • 四 定制绘图风格 五 数据生成导入六 三维动态演示
  • 坐标列表进阶:导出数据系统菜单批量文件导入辅助坐标轴
  • 绘图类型进阶:坐标映射八种绘图函数

封装绘图函数

DrawType类封装了子图位置、坐标轴映射类型以及绘图类型,就基本可以确定绘图坐标以及绘图函数了。

此前,这一步是在DrawSystem中完成的,这显然增加了DrawSystem的负担,若将其挪到DrawType中,显然是更加合理的。甚至于,绘图用的坐标轴和用于绘图的函数,理应成为DrawType的全局变量。

# 如果给定了ax,说明与其他绘图函数公用坐标轴
def setDrawFunc(self, fig, ax=None, **options):
    if not ax:
        sub = int(self.getSub())
        proj = self.getProj() if self.getProj()!="None" else None
        ax = fig.add_subplot(sub, projection=p, **options)
    self.ax = ax        
    
    funcDct = {
        "点线图": ax.plot,    "曲线图" : ax.plot, 
        "散点图": ax.scatter, 
        "图像"  : ax.imshow,  "伪彩图" : ax.pcolormesh, 
        "条形图": ax.bar,     "横向条形图": ax.barh, 
        "茎叶图": ax.stem,    "阶梯图": ax.step
    }
    self.draw = funcDct[self.getType()]
    return self.draw

前面的逻辑很清晰,如果外部传入了坐标轴,那么就不必再新建一个坐标轴了。后面需要注意funcDct切记不可做成全局变量,而必须建在ax创建之后,因为这里面所调用的所有对象,都是当前坐标轴ax的成员函数。

点线图 ax.plot 曲线图 ax.plot
散点图 ax.scatter
图像 ax.imshow 伪彩图 ax.pcolormesh
条形图 ax.bar 横向条形图 ax.barh
茎叶图 ax.stem 阶梯图 ax.step

绘图系统简单的修改

这个功能在创建之后,需要更改DrawSystem才能验证,并且还涉及到更改AxisList。这里只对DrawSytstem做一个简单的改动,首先添加setDrawFunc函数

def setDrawFunc(self, al):
    sub = int(al.getSub())
    ax = None if sub not in self.axDct else self.axDct[sub]
    ax, draw = al.drawType.setDrawFunc(self.fig, ax)
    self.axDct[sub] = ax
    return draw

然后更改btnDrawImg函数

def btnDrawImg(self):
    self.fig.clf()
    self.axDct = {}
    for al in self.als:
        data = self.readDatas(al)
        draw = self.setDrawFunc(al)
        style = al.getStyle()
        keys = al.getXYZ()
        draw(*[data[key] for key in keys], **style)
    self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)
    self.canvas.draw()

最后效果如下,十分强大

源代码

最后附上base.py中的DrawType类的源代码。

# 绘图类型和维度
# varDct 的格式是 {"sub":sub, "type":slctType, "dim":dim, "proj": proj}

class DrawType(ttk.Frame):
    # ws为两个combobox的宽
    def __init__(self, master, 
        varDct = {"sub":"111", "type":'点线图', "dim":"xyz", "proj": "3d"},
        ws=None, func=None, **options):
        super().__init__(master, **options)
        self.pack()
        self.dimChanged = func
        self.initConst()
        self.initVar(varDct)
        self.initWidgets(ws)

    def initVar(self, varDct):
        self.drawVars = {key:tk.StringVar() for key in varDct}
        for key in self.drawVars:
            self.drawVars[key].set(varDct[key])

    def initConst(self):
        self.TYPES = [
            "点线图", "曲线图", "散点图", "图像", "伪彩图", 
            "条形图", "横向条形图", "茎叶图", "阶梯图"]

    def initWidgets(self, ws):
        if ws==None: ws = [5, 5, 5, 3]
        slctDct = {'type': self.TYPES, 
            'proj': ("None", "3d", "polar"), 
            'dim' : ("x", "xy", "xyz")}    # 绘图维度

        keys = ['sub', 'type', 'proj', 'dim']
        self.wDct = {}  # 控件字典

        # 此为设置子图的Entry控件
        self.wDct['sub'] = ttk.Entry(self, width=ws[0], 
            textvariable=self.drawVars['sub'])

        for i, key in enumerate(keys[1:], 1):
            self.wDct[key] = ttk.Combobox(self, width=ws[i], 
                textvariable=self.drawVars[key])
            self.wDct[key]['value'] = slctDct[key]

        for key in keys:
            self.wDct[key].pack(side=tk.LEFT, padx=2)

        self.wDct['type'].bind('<>', self.cbTypeChanged)
        self.wDct['proj'].bind('<>', self.cbProjChanged)
        self.wDct['dim'].bind('<>', self.dimChanged)
        
    def cbTypeChanged(self, evt):
        t = self.drawVars['type'].get()
        p = self.drawVars['proj'].get()
        if t in ("图像"):
            self.wDct['proj']['value'] =  ("None")
        elif t in ("横向条形图", "伪彩图"):
            self.wDct['proj']['value'] =  ("None", "polar")
        else:
            self.wDct['proj']['value'] =  ("None", "3d", "polar")
        
        projs = self.wDct['proj']['value']
        if p not in projs:
            self.drawVars['proj'].set(projs[0])        
        self.cbProjChanged(None)

    def cbProjChanged(self, evt):
        p = self.drawVars['proj'].get()
        func = {
            'None': self.cbProjNone,
            '3d': self.cbProj3d,
            'polar' : self.cbProjPolar}
        
        d = self.wDct['dim'].get()
        t = self.drawVars['type'].get()
        func[p](t)
        dims = self.wDct['dim']['value']
        if d not in dims:
            self.drawVars['dim'].set(dims[0])
        self.dimChanged(None)

    def cbProjNone(self, t):
        if t in ("点线图", "曲线图"):
            self.wDct['dim']['value'] = ('x', 'xy')
        elif t in ("图像"):
            self.wDct['dim']['value'] = ('x')
        elif t in ("伪彩图"):
            self.wDct['dim']['value'] = ('x', 'xyz')
        else:
            self.wDct['dim']['value'] = ('xy')

    def cbProjPolar(self, t):
        if t in ("点线图", "曲线图"):
            self.wDct['dim']['value'] = ('x', 'xy')
        elif t in ("伪彩图"):
            self.wDct['dim']['value'] = ('xyz')
        else:
            self.wDct['dim']['value'] = ('xy')

    def cbProj3d(self, t):
        self.wDct['dim']['value'] = ('xy', 'xyz')

    # 如果给定了ax,说明与其他绘图函数公用坐标轴
    def setDrawFunc(self, fig, ax=None, **options):
        if not ax:
            sub = int(self.getSub())
            p = self.getProj() if self.getProj()!="None" else None
            ax = fig.add_subplot(sub, projection=p, **options)
        self.ax = ax        
        
        funcDct = {
            "点线图": ax.plot,    "曲线图" : ax.plot, 
            "散点图": ax.scatter, 
            "图像"  : ax.imshow,  "伪彩图" : ax.pcolormesh, 
            "条形图": ax.bar,     "横向条形图": ax.barh, 
            "茎叶图": ax.stem,    "阶梯图": ax.step
        }
        self.draw = funcDct[self.getType()]
        return self.ax, self.draw
    
    def setFunc(self):
        self.ax

    def getSub(self):
        return self.drawVars['sub'].get()

    def getType(self): 
        return self.drawVars['type'].get()
    
    def getDim(self):
        return self.drawVars['dim'].get()

    def getProj(self):
        return self.drawVars['proj'].get()

    def getDct(self):
        return {key:self.drawVars[key].get() for key in self.drawVars}

你可能感兴趣的:(#,python,tkinter,matplotlib,Axes,绘图系统)