我如何使用 wxpython 在矩形块的矩阵 5x5 中显示 25 个像素值 [英] how i can show 25 values of pixels in matrix 5x5 of rectangle patch using wxpython

查看:38
本文介绍了我如何使用 wxpython 在矩形块的矩阵 5x5 中显示 25 个像素值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道如何像其他面板中的板一样读取和显示矩阵 5x5(5 行 5 列)的矩形块内所有像素的值

我做这个例子只是为了解释我需要做什么:

我需要在 paneltwo 中显示的内容就像这个例子:

代码:

import wx将 numpy 导入为 np导入 netCDF4从 netCDF4 导入数据集从 matplotlib.backends.backend_wxagg 导入 FigureCanvasWxAgg 作为 FigureCanvasfrom matplotlib.figure 导入图导入 matplotlib.patches 作为补丁导入 matplotlib类窗口(wx.Frame):def __init__(self, **kwargs):super().__init__(None, **kwargs)根面板(自己)类 RootPanel(wx.Panel):def __init__(self, parent):super().__init__(parent)panel_buttons = wx.Panel(self)panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)self.canvas_panel = CanvasPanel(self)self.panel_two = PanelTwo(parent=self)选择按钮 = 选择按钮(面板按钮,"netCDF4 文件 (nc)|*.nc",self.canvas_panel.load_from_file,label="显示在此窗口 (nc)",)toplevel_select_button = TopLevelPickButton(面板按钮,"文本文件(txt)|*.txt|所有文件|*.*",label="显示在单独的窗口 (txt)",)panel_buttons_sizer.Add(select_button)panel_buttons_sizer.Add(toplevel_select_button)panel_buttons.SetSizer(panel_buttons_sizer)canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)canvas_sizer.Add(self.panel_two,1,wx.EXPAND)sizer = wx.BoxSizer(wx.VERTICAL)sizer.Add(panel_buttons)sizer.Add(canvas_sizer)self.SetSizerAndFit(sizer)self.Show()类 PickButton(wx.Button):def __init__(self, parent, 通配符, func, **kwargs):super().__init__(parent, **kwargs)self.wildcard = 通配符self.func = funcself.Bind(wx.EVT_BUTTON, self.pick_file)def pick_file(self, evt):样式 = 样式 = wx.FD_OPEN |wx.FD_FILE_MUST_EXIST |wx.FD_MULTIPLE与 wx.FileDialog(self, "选择文件", 通配符=self.wildcard, style=style) 作为文件对话框:如果 fileDialog.ShowModal() != wx.ID_CANCEL:selected_file = fileDialog.GetPath()self.func(chosen_file)类 TopLevelPickButton(PickButton):def __init__(self, parent, 通配符, **kwargs):super().__init__(parent, 通配符, self.create_toplevel, **kwargs)def create_toplevel(self, file_name):""" Ouvre une toplevel et affiche le graphique """self.win = TopLevelCanvas(self.Parent)self.win.canvas_panel.load_from_file(file_name)self.win.Show()类 CanvasPanel(wx.Panel):""" Panel du graphique matplotlib """def __init__(self, parent, size=(200,250)):super().__init__(parent)self.figure = Figure(figsize =(5,5))self.canvas = FigureCanvas(self, -1, self.figure)self.Size = self.canvas.Sizeself.parent = 父母def load_from_file(self, file_name):self.axes = self.figure.add_subplot(111)如果 file_name.endswith(".nc"):self._load_nc(file_name)别的:self._load_txt(file_name)self.canvas.draw()def _load_txt(self, file_name):self._load_nc(file_name)def _load_nc(self, file_name):fic='air.departure.sig995.2012.nc'路径='D:/数据/'nc = netCDF4.Dataset(path+fic,'r')lons = nc.variables['lon'][:]lats = nc.variables['lat'][:]air_dep = nc.variables['air_dep'][:,:,:]air_dep = air_dep[0,:,:]self.axes.imshow(air_dep)self.canvas.mpl_connect('button_press_event', self.on_press)x = y = 1self.rect = patch.Rectangle((x, y), 5,5,edgecolor='r', alpha=1, fill=None, label='Label')self.axes.add_patch(self.rect)self.axes.plot()self.Show()def on_press(self, click):x1, y1 = click.xdata, click.ydataself.parent.panel_two.Update(x1,y1)zx1 = x1 - 2.5zy1 = y1 - 2.5zx2 = x1 + 2.5zy2 = y1 + 2.5self.rect.set_x(x1 - 2.5) #移动矩形并以X点击点为中心self.rect.set_y(y1 - 2.5) #移动矩形并以Y点击点为中心self.axes.plot()self.canvas.draw()class PanelTwo(wx.Panel): #here 当我需要可视化像素和坐标光标时def __init__(self,parent):wx.Panel.__init__(self,parent,size=(300,250))self.text_ctrl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2, size=(200,170))lbl = wx.StaticText(self,label="坐标光标和像素")sizer = wx.BoxSizer(wx.VERTICAL)sizer.Add(lbl,0, wx.ALIGN_CENTRE,10)sizer.Add(self.text_ctrl,0, wx.ALIGN_CENTRE,10)self.SetSizer(sizer)定义更新(自我,x1,y1):self.text_ctrl.SetValue("鼠标点击;\nX "+str(x1)+"\nY "+str(y1))类 TopLevelCanvas(wx.Frame):def __init__(self, parent, **kwargs):super().__init__(parent, **kwargs)self.canvas_panel = CanvasPanel(self)self.zoom_panel = Zoom(parent=self)self.Size = self.canvas_panel.Sizecanvas_sizer = wx.BoxSizer(wx.HORIZONTAL)canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)self.SetSizerAndFit(canvas_sizer)self.Show()类应用程序(wx.App):def OnInit(self):win = Window(title="一个测试对话框", size=(1000, 800))win.Show()返回真如果 __name__ == "__main__":应用程序 = 应用程序()app.MainLoop()

也许我需要在这行代码中使用类似的东西:**air_dep[x-5:x+5,y-5:y+5]**:

def on_press(self, click):x1, y1 = click.xdata, click.ydataself.parent.panel_two.Update(x1,y1)

我如何在所有列和行的示例中显示矩阵或板等值?

谢谢

其他文件 netcdf4:

i need to know how i can read and show values of all pixel inside rectangle patch of matrix 5x5 ( 5 rows , 5 column) like a board in other panel

i do this example just to explain what i need to do :

what i need to show in paneltwo is like this example :

that the code :

import wx
import numpy as np
import netCDF4
from netCDF4 import Dataset
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.patches as patches
import matplotlib

class Window(wx.Frame):


    def __init__(self, **kwargs):
        super().__init__(None, **kwargs)
        RootPanel(self)

class RootPanel(wx.Panel):


    def __init__(self, parent):
        super().__init__(parent)

        panel_buttons = wx.Panel(self)
        panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)

        self.canvas_panel = CanvasPanel(self)
        self.panel_two = PanelTwo(parent=self)

        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            self.canvas_panel.load_from_file,
            label="Show on this window (nc)",
        )
        toplevel_select_button = TopLevelPickButton(
            panel_buttons,
            "Text files (txt)|*.txt|All files|*.*",
            label="Show on separate window (txt)",
        )
        panel_buttons_sizer.Add(select_button)
        panel_buttons_sizer.Add(toplevel_select_button)
        panel_buttons.SetSizer(panel_buttons_sizer)

        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.panel_two,1,wx.EXPAND)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel_buttons)
        sizer.Add(canvas_sizer)
        self.SetSizerAndFit(sizer)
        self.Show()

class PickButton(wx.Button):


    def __init__(self, parent, wildcard, func, **kwargs):

        super().__init__(parent, **kwargs)
        self.wildcard = wildcard
        self.func = func
        self.Bind(wx.EVT_BUTTON, self.pick_file)

    def pick_file(self, evt):
        style = style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
        with wx.FileDialog(
            self, "Pick files", wildcard=self.wildcard, style=style
        ) as fileDialog:
            if fileDialog.ShowModal() != wx.ID_CANCEL:
                chosen_file = fileDialog.GetPath()
                self.func(chosen_file)

class TopLevelPickButton(PickButton):


    def __init__(self, parent, wildcard, **kwargs):
        super().__init__(parent, wildcard, self.create_toplevel, **kwargs)

    def create_toplevel(self, file_name):
        """ Ouvre une toplevel et affiche le graphique """
        self.win = TopLevelCanvas(self.Parent)
        self.win.canvas_panel.load_from_file(file_name)
        self.win.Show()

class CanvasPanel(wx.Panel):
    """ Panel du graphique matplotlib """
    def __init__(self, parent , size=(200,250)):
        super().__init__(parent)
        self.figure = Figure(figsize =(5,5))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size
        self.parent = parent

    def load_from_file(self, file_name):

        self.axes = self.figure.add_subplot(111)
        if file_name.endswith(".nc"):
            self._load_nc(file_name)
        else:
            self._load_txt(file_name)
        self.canvas.draw()

    def _load_txt(self, file_name):
        self._load_nc(file_name)

    def _load_nc(self, file_name):

        fic='air.departure.sig995.2012.nc'

        path='D:/data/'


        nc = netCDF4.Dataset(path+fic,'r')
        lons = nc.variables['lon'][:]
        lats = nc.variables['lat'][:]
        air_dep = nc.variables['air_dep'][:,:,:]
        air_dep = air_dep[0,:,:]


        self.axes.imshow(air_dep)

        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = 1
        self.rect = patches.Rectangle((x, y), 5,5,edgecolor='r', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)
        self.axes.plot()
        self.Show()

    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        self.parent.panel_two.Update(x1,y1)
        zx1 = x1 - 2.5
        zy1 = y1 - 2.5
        zx2 = x1 + 2.5
        zy2 = y1 + 2.5
        self.rect.set_x(x1 - 2.5) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 2.5) #Move the rectangle and centre it on the Y click point


        self.axes.plot()
        self.canvas.draw()



class PanelTwo(wx.Panel): #here when i need to visualize pixel and coordinator cursor
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(300,250))

        self.text_ctrl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2, size=(200,170))

        lbl = wx.StaticText(self,label="Coordinato cursor & Pixel ")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(lbl,0, wx.ALIGN_CENTRE,10)
        sizer.Add(self.text_ctrl,0, wx.ALIGN_CENTRE,10)
        self.SetSizer(sizer)

    def Update(self,x1,y1):
        self.text_ctrl.SetValue("Mouse click at;\nX "+str(x1)+"\nY "+str(y1))



class TopLevelCanvas(wx.Frame):


    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel = Zoom(parent=self)
        self.Size = self.canvas_panel.Size
        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        self.SetSizerAndFit(canvas_sizer)
        self.Show()

class App(wx.App):
    def OnInit(self):
        win = Window(title="A test dialog", size=(1000, 800))
        win.Show()
        return True

if __name__ == "__main__":
    app = App()
    app.MainLoop()

is maybe i need to use something like : **air_dep[x-5:x+5,y-5:y+5]** in this line of code :

def on_press(self, click):
            x1, y1 = click.xdata, click.ydata
            self.parent.panel_two.Update(x1,y1)

how i can show the values like matrix or board in example with all column and rows ?

thank you

other file netcdf4 : https://drive.google.com/open?id=1IT-F7AbIx4bCjMLosjBx4F4UCoIX5DU0 here

解决方案

Currently the 5x5 grid is written into the 2nd panel, you could create a separate panel for them.
The 5x5 grid is a bit hacky, as around the edges the grid can become 3x5 or 5x3 and in the corners it has to become 3x3.

import wx
import numpy as np
import netCDF4
from netCDF4 import Dataset
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.patches as patches
import matplotlib

class Window(wx.Frame):
    """ Fenêtre principale de l'application """

    def __init__(self, **kwargs):
        super().__init__(None, **kwargs)
        RootPanel(self)

class RootPanel(wx.Panel):
    """ Panel contenant tous les autres widgets de l'application """

    def __init__(self, parent):
        super().__init__(parent)

        panel_buttons = wx.Panel(self)
        panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)

        self.canvas_panel = CanvasPanel(self)
        self.panel_two = PanelTwo(parent=self)

        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            self.canvas_panel.load_from_file,
            label="Show on this window (nc)",
        )
        toplevel_select_button = TopLevelPickButton(
            panel_buttons,
            "Text files (txt)|*.txt|All files|*.*",
            label="Show on separate window (txt)",
        )
        panel_buttons_sizer.Add(select_button)
        panel_buttons_sizer.Add(toplevel_select_button)
        panel_buttons.SetSizer(panel_buttons_sizer)

        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.panel_two,1,wx.EXPAND)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel_buttons)
        sizer.Add(canvas_sizer)
        self.SetSizerAndFit(sizer)
        self.Show()

class PickButton(wx.Button):
    """ Bouton permettant de choisir un fichier """

    def __init__(self, parent, wildcard, func, **kwargs):
        # func est la méthode à laquelle devra être foruni le fichier sélectionné
        super().__init__(parent, **kwargs)
        self.wildcard = wildcard
        self.func = func
        self.Bind(wx.EVT_BUTTON, self.pick_file)

    def pick_file(self, evt):
        style = style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
        with wx.FileDialog(
            self, "Pick files", wildcard=self.wildcard, style=style
        ) as fileDialog:
            if fileDialog.ShowModal() != wx.ID_CANCEL:
                chosen_file = fileDialog.GetPath()
                self.func(chosen_file)

class TopLevelPickButton(PickButton):
    """ Permet de choisir un fichier et d'ouvrir une toplevel """

    def __init__(self, parent, wildcard, **kwargs):
        super().__init__(parent, wildcard, self.create_toplevel, **kwargs)

    def create_toplevel(self, file_name):
        """ Ouvre une toplevel et affiche le graphique """
        self.win = TopLevelCanvas(self.Parent)
        self.win.canvas_panel.load_from_file(file_name)
        self.win.Show()

class CanvasPanel(wx.Panel):
    """ Panel du graphique matplotlib """
    def __init__(self, parent , size=(200,250)):
        super().__init__(parent)
        self.figure = Figure(figsize =(5,3))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size
        self.parent = parent

    def load_from_file(self, file_name):
        """
        Méthode effectuant l'intermédiaire pour charger le fichier selon
        son type
        """
        self.axes = self.figure.add_subplot(111)
        if file_name.endswith(".nc"):
            self._load_nc(file_name)
        else:
            self._load_txt(file_name)
        self.canvas.draw()

    def _load_txt(self, file_name):
        self._load_nc(file_name)

    def _load_nc(self, file_name):
        """ Simule le chargement et affichage à partir d'un fichier nc """
        fic='air.departure.sig995.2012.nc'

        #path='/home/data/'
        path=''


        nc = netCDF4.Dataset(path+fic,'r')
#        print("model",nc.data_model)
#        print("groups",nc.groups)
#        print("dimensions",nc.dimensions)
#        print("variables",nc.variables)
#        for dimobj in nc.dimensions.values():
#            print(dimobj)
#        for name in nc.ncattrs():
#            print("Global attr", name, "=", getattr(nc,name))

        self.lons = nc.variables['lon'][:]
        self.lats = nc.variables['lat'][:]
        air_dep = nc.variables['air_dep'][:,:,:]
        self.lonl = len(self.lons) -1
        self.latl = len(self.lats) -1

        self.air_dep = air_dep[0,:,:]

        self.axes.imshow(self.air_dep)

        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = 1
        self.rect = patches.Rectangle((x, y), 5,5,edgecolor='r', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)

    def float_to_dms(self,f,orientation):
        # convert to seconds
        f = f * 3600
        if f < 0:
            div1 = -3600
            div2 = -1
        else:
            div1 = 3600
            div2 = 1
        #Degrees,minutes,seconds
        d,m = divmod(f,div1)
        m,s = divmod(m*60,div1)
        s, x = divmod(s*60,div1)

        d,x = divmod(d,div2)
        m,x = divmod(m,1)
        s,x = divmod(s,1)

        return (orientation+" "+str(int(d))+"° "+str(int(m)).zfill(2)+"' "+str(int(s)).zfill(2)+'"\n')

    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        #Longititude values are 2.5 degrees apart for this data
        try:
            lon = x1*2.5
        except:
            print("Out of bounds - Click again")
            return
        if lon < 180.0:
            Ew = "E"
        else:
            Ew = "W"
            lon = (lon - 360.0) -1
        #Latitude values from 90 to -90 2.5 degrees apart
        #split the y value
        i,f = divmod(y1,1)
        lat = self.lats[int(i)]
        #calculate the fraction of degrees
        if lat > 0 and lat < 87.5:
            lat = lat+(f*2.5)
        elif lat < 0 and lat > -87.5:
            lat = lat-(f*2.5)
        if lat < 0.0:
            Ns= "S"
        else:
            Ns = "N"
        #Convert to ° ' "
        lon_dms = self.float_to_dms(lon,Ew)
        lat_dms = self.float_to_dms(lat,Ns)

        #air_dep seems the wrong way round but what do I know
        #The way below gives values that seem correct
        air = self.air_dep[int(y1),int(x1)]
        air_rect =[]
        x = int(x1)
        y = int(y1)
        # Build valid values for rectangle
        # to cater for values beyond the edge of the map
        if x-1 < 0: x2 = 0
        else: x2 = x-2
        if x+2 > self.lonl: x3 = self.lonl+1
        else: x3 = x+3
        if y-2 < 0:
            pass
        else:
            air_rect.append(self.air_dep[y-2,x2:x3])
        if y-1 < 0:
            pass
        else:
            air_rect.append(self.air_dep[y-1,x2:x3])
        air_rect.append(self.air_dep[y,x2:x3])
        if y+1 > self.latl:
            pass
        else:
            air_rect.append(self.air_dep[y+1,x2:x3])
        if y+2 > self.latl:
            pass
        else:
            air_rect.append(self.air_dep[y+2,x2:x3])

        self.parent.panel_two.Update(x1,y1,lon,lat,air,lon_dms,lat_dms,Ns,Ew,air_rect)
        zx1 = x1 - 2.5
        zy1 = y1 - 2.5
        zx2 = x1 + 2.5
        zy2 = y1 + 2.5
        self.rect.set_x(x1 - 2.5) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 2.5) #Move the rectangle and centre it on the Y click point
        self.axes.plot()
        self.canvas.draw()



class PanelTwo(wx.Panel): #here when i need to visualize pixel and coordinator cursor
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(300,250))

        self.text_ctrl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2, size=(300,300))

        lbl = wx.StaticText(self,label="Coordinato cursor & Pixel ")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(lbl,0, wx.ALIGN_CENTRE,10)
        sizer.Add(self.text_ctrl,0, wx.ALIGN_CENTRE,10)
        self.SetSizer(sizer)

    def Update(self,x1,y1,lon,lat,air,lon_dms,lat_dms,Ns,Ew,air_rect):
        update_str = "Mouse click at;\nX "+str(x1)+"\nLon "+Ew+" "+str(lon)+"\n"+lon_dms+"\nY "+str(y1)+"\nLat "+Ns+" "+str(lat)+"\n"+lat_dms+"\nAir Value at point "+str(air)+"\n"
        self.text_ctrl.SetValue(update_str)
        self.text_ctrl.write("Surrounding values\n")
        #Table of surrounding temperatures
        for i in range(len(air_rect)):
            s = ""
            line = air_rect[i]
            for i2 in line:
                s+="{:5.1f}".format(i2)+"  "
            self.text_ctrl.write(s+"\n")

class TopLevelCanvas(wx.Frame):
    """ Fenêtre affichant uniquement un graph matplotlib """

    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel = Zoom(parent=self)
        self.Size = self.canvas_panel.Size
        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        self.SetSizerAndFit(canvas_sizer)
        self.Show()

class App(wx.App):
    def OnInit(self):
        win = Window(title="A test dialog", size=(1000, 800))
        win.Show()
        return True

if __name__ == "__main__":
    app = App()
    app.MainLoop()

这篇关于我如何使用 wxpython 在矩形块的矩阵 5x5 中显示 25 个像素值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆