解窗口分割和动态折线图绘制

警 告 : 本 博 客 所 写 内 容 严 禁 盗 用 , 违 者 必 究 ! 转 发 请 标 明 出 处 \color{red}{警告:本博客所写内容严禁盗用,违者必究! 转发请标明出处}

静态折线图绘制

本功能模块参考如影随形的绘制正弦曲线,如影随形源代码如下

下面代码引用如影随形《用wxpython 和numpy话画正弦曲线》

#-*- coding: utf-8 -*-    
  
################################################################################   
## 使用wxPython的绘图模块wxPyPlot,需要数据可视化的时候,无需再借用其他的库或模块了   
################################################################################   
import numpy  
import wx  
import wx.lib.plot as wxPyPlot #导入绘图模块,并命名为wxPyPlot   
  
#---------------------------------------------------------------------------   
# 需要把数据封装进入MyDataObject中   
def MyDataObject():  
    # 50 个点的sin函数,用蓝色圆点表示   
    data1 = 2.*numpy.pi*numpy.arange(100)/100.  
    data1.shape = (50, 2)  
    data1[:,1] = numpy.sin(data1[:,0])  
    markers = wxPyPlot.PolyMarker(data1, legend='Green Markers', colour='blue', marker='circle',size=1)  
  
    # 50个点的cos函数,用红色表示   
    data2 = 2.*numpy.pi*numpy.arange(100)/100.  
    data2.shape = (50,2)  
    data2[:,1] = numpy.cos(data2[:,0])  
    lines = wxPyPlot.PolyLine(data2, legend= 'Red Line', colour='red')  
      
    GraphTitle="Plot Data(Sin and Cos)"  
  
      
    return wxPyPlot.PlotGraphics([markers, lines],GraphTitle, "X Axis", "Y Axis")  
#-----------------------------------------------------------------------------   
class TestFrame1(wx.Frame):  
    def __init__(self, parent=None, id=wx.ID_ANY, title="Using wxPyPlot"):  
        wx.Frame.__init__(self, parent, id, title,size=(600, 400))  
          
        # 创建菜单栏   
        self.mainmenu = wx.MenuBar()  
  
        menu = wx.Menu()  
        menu.Append(100, 'Draw1', 'Draw plots1')  
        self.Bind(wx.EVT_MENU,self.OnPlotDraw1, id=100)  
  
        self.mainmenu.Append(menu, '&Plot')  
  
        self.SetMenuBar(self.mainmenu)  
  
        # 创建状态栏,显示信息   
        self.CreateStatusBar(2)  
         
        self.pc = wxPyPlot.PlotCanvas(self) #此处导入绘图面板   
  
    def OnPlotDraw1(self, event): #绘图函数   
        self.pc.Draw(MyDataObject())  
  
  
###########################################################################   
## 测试wxPyPlot的代码   
###########################################################################   
if __name__=='__main__':  
        app = wx.App()  
        tf=TestFrame1(None)  
        tf.Show()  
        app.MainLoop()  
###########################################################################   
  
########################################################################### 

程序效果图为:
在这里插入图片描述

动态绘制折线

我们要实现动态图的绘制,就需要绘图动起来,所以我对程序做了去下修改,去掉了numpy模块,改用random来实现数据模拟代码如下

# -*- coding: utf-8 -*-

################################################################################
## 使用wxPython的绘图模块wxPyPlot,需要数据可视化的时候,无需再借用其他的库或模块了
################################################################################
import random
from time import sleep

import wx
import wx.lib.plot as wxPyPlot  # 导入绘图模块,并命名为wxPyPlot


# ---------------------------------------------------------------------------
# 需要把数据封装进入MyDataObject中
def MyDataObject():
    data1 = [[i,random.randint(0,9)] for i in range(100)]
    lines1 = wxPyPlot.PolyLine(data1, legend='Green Markers', colour='blue')
    data2 = [[i,random.randint(0,9)] for i in range(100)]
    lines2 = wxPyPlot.PolyLine(data2, legend='Red Line', colour='red')

    GraphTitle = "动态图的绘制"

    return wxPyPlot.PlotGraphics([lines1, lines2], GraphTitle, "X", "Y")


# -----------------------------------------------------------------------------
class TestFrame1(wx.Frame):
    def __init__(self, parent=None, id=wx.ID_ANY, title="Using wxPyPlot"):
        wx.Frame.__init__(self, parent, id, title, size=(600, 400))

        # 创建菜单栏
        self.mainmenu = wx.MenuBar()

        menu = wx.Menu()
        menu.Append(100, 'Draw1', 'Draw plots1')
        self.Bind(wx.EVT_MENU, self.OnPlotDraw1, id=100)

        self.mainmenu.Append(menu, '&Plot')

        self.SetMenuBar(self.mainmenu)

        # 创建状态栏,显示信息
        self.CreateStatusBar(2)

        self.pc = wxPyPlot.PlotCanvas(self)  # 此处导入绘图面板

    def OnPlotDraw1(self, event):  # 绘图函数
        while True:

            self.pc.Draw(MyDataObject())
            sleep(2)

    ###########################################################################


## 测试wxPyPlot的代码
###########################################################################
if __name__ == '__main__':
    app = wx.App()
    tf = TestFrame1(None)
    tf.Show()
    app.MainLoop()
###########################################################################

###########################################################################

在这里插入图片描述
上面例子基本实现了数据的动态刷新,由于在事件函数动作的内部死循环,造成了wxpython界面的卡死,后面做功能组合的时候必须考虑多线程和定时器的使用。

窗口分割——水平分割窗口

本功能模块参考如影随形的绘制正弦曲线,如影随形源代码如下

下面代码引用 duzanuolu wxpython分割窗研究(解决sashPosition=0无效的BUG)

import wx
class Myframe(wx.Frame):
    def __init__(self,flag=False):
        wx.Frame.__init__(self,None)
        self.sp=wx.SplitterWindow(self)# 创建一个分割窗
        self.flag=flag
        self.fisrt=0
        self.p1=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)  #创建子面板
        self.p2=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)
        self.p1.SetBackgroundColour("pink")
        self.p2.SetBackgroundColour("blue")
        self.p1.Hide()  # 确保备用的子面板被隐藏
        self.p2.Hide()
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
        self.sp.Unsplit()
        self.sp.SplitHorizontally(self.p1, self.p2)
    def OnEraseBack(self,event):
        if self.fisrt<2 or self.flag :
            self.sp.SetSashPosition(0)
            self.fisrt=self.fisrt+1
        event.Skip()
app = wx.App()
frame=Myframe(True)
frame.Show(True)
app.MainLoop()

可能他的代码用的wxpython版本太早了,现在运行有点问题,需要将wx.PySimpleApp()改为wx.App(),运行效果如下
在这里插入图片描述

分割窗口与绘画整合

整合分割窗口和绘图,使图形界面绘制在下面的分割窗口,代码如下:

import wx
import wx.lib.plot as wxPyPlot  # 导入绘图模块,并命名为wxPyPlot
import random

def MyDataObject():
    data1 = [[i,random.randint(0,9)] for i in range(100)]
    lines1 = wxPyPlot.PolyLine(data1, legend='Green Markers', colour='blue')
    data2 = [[i,random.randint(0,9)] for i in range(100)]
    lines2 = wxPyPlot.PolyLine(data2, legend='Red Line', colour='red')

    GraphTitle = "动态图的绘制"

    return wxPyPlot.PlotGraphics([lines1, lines2], GraphTitle, "X", "Y")


class Myframe(wx.Frame):
    def __init__(self,flag=False):
        wx.Frame.__init__(self,None,size=(800,600))
        self.mainmenu = wx.MenuBar()

        menu = wx.Menu()
        menu.Append(100, 'Draw1', 'Draw plots1')

        self.mainmenu.Append(menu, '&Plot')

        self.SetMenuBar(self.mainmenu)

        self.sp=wx.SplitterWindow(self)# 创建一个分割窗
        self.flag=flag
        self.fisrt=0
        self.p1=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)  #创建子面板
        self.p2=wx.Panel(self.sp,style=wx.SUNKEN_BORDER)
        self.p1.SetBackgroundColour("pink")
        self.p2.SetBackgroundColour("#255255255255")
        self.p1.Hide()  # 确保备用的子面板被隐藏
        self.p2.Hide()
        self.plotter = wxPyPlot.PlotCanvas(self.p2, size=(800, 200))
        self.plotter.SetInitialSize(size=self.p2.GetBestSize())
        self.sp.Unsplit()
        self.sp.SplitHorizontally(self.p1, self.p2)

        self.Bind(wx.EVT_MENU, self.OnPlotDraw1)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBack)
    def OnEraseBack(self,event):
        if self.fisrt<2 or self.flag :
            self.sp.SetSashPosition(0)
            self.fisrt=self.fisrt+1
        event.Skip()

    def OnPlotDraw1(self, event):  # 绘图函数
        self.plotter.Draw(MyDataObject())
        event.Skip()

app = wx.App()
frame=Myframe(True)
frame.Show(True)
app.MainLoop()

运行结果如下:
在这里插入图片描述
下一章博客将所有空间集中在一个窗口

特别感谢

本系列博客参考博客内容有以下帖子:
参考:wxFormBuilder摸索–小白上手–做一个编辑器,感谢caiza3491的技术分享
参考:wxpython分割窗研究(解决sashPosition=0无效的BUG),感谢duzanuolu的系列技术分享
参考:wxPython长时间任务处理,感谢CommandM的技术分享
参考:用wxpython 和numpy话画正弦曲线,感谢如影随形的技术分享

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐