我如何使用 wxpython 在矩形块的矩阵 5x5 中显示 25 个像素值 [英] how i can show 25 values of pixels in matrix 5x5 of rectangle patch using wxpython
问题描述
我需要知道如何像其他面板中的板一样读取和显示矩阵 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屋!