File "/home/tm.py", line 126, in on_press self.GrandParent.panel.three.Update(x1,y1,lon,lat,vis006) AttributeError: 'NoneType' object has no attribute 'panel' >>>
how can i fix this error ? to show rectangle in panel&paneltwo in the same time
the second problem that i need to showing the value of variable VIS006 for panel and IR2 for paneltwo in the panelthree the same time when i click in rectangle in panel i can get information about panel and paneltwo in panelthree !
thank you
that the example code :
import wx
import numpy as np
import netCDF4
import h5py
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
import matplotlib.pyplot as plt
class MainFrame(wx.Frame):
""" Fenêtre principale de l'application """
def __init__(self, parent):
super().__init__(parent,size = (2000,950))
global x1, y1
self.root = RootPanel(self)
self.panel=Panel(self)
self.panel_two=PanelTwo(self)
sizer1 = wx.BoxSizer(wx.HORIZONTAL)
sizer1.Add(self.root, 1, wx.EXPAND)
sizer1.Add(self.panel, 1, wx.EXPAND)
sizer1.Add(self.panel_two, 1, wx.EXPAND)
self.SetSizer(sizer1)
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_three = PanelThree(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_three,1,wx.EXPAND)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel_buttons)
sizer.Add(canvas_sizer)
self.SetSizerAndFit(sizer)
self.Show()
class Panel(wx.Panel):
def __init__(self,parent):
super().__init__(parent,size=(200,200))
def Update(self,parent):
#Load axis values of the selected rectangle
zoom_axes=parent.zoom_axes
self.figure = Figure(figsize =(5,4))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
self.figure.subplots_adjust(left=0.009,right=0.99,bottom=0.09,top=0.99)
self.axes.axis(zoom_axes)
fic='Mmultic3kmNC4_msg04_201905080200.nc'
path='/data/'
#path=''
fic1='/data/latlon_+000.0_globe.nc'
nc = netCDF4.Dataset(path+fic,'r')
vis006 = nc.variables['VIS006'][:]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.lons = lons[:]
self.lats = lats[:]
self.vis006 = vis006[:]
self.axes.imshow(self.vis006 ,cmap=plt.cm.gist_yarg)
self.canvas.mpl_connect('button_press_event', self.on_press)
x = y = 0.05
self.rect = patches.Rectangle((x, y), 0.1,0.1,edgecolor='r', alpha=1, fill=None, label='Label')
self.axes.add_patch(self.rect)
self.figure.add_axes(self.axes)
'self.figure.show()'
self.axes.plot()
def on_press(self, click):
x1, y1 = click.xdata, click.ydata
#air_dep seems the wrong way round but what do I know
#The way below gives values that seem correct
vis006 = self.vis006[int(y1),int(x1)]
lon = self.lons[int(y1),int(x1)]
lat = self.lats[int(y1),int(x1)]
self.GrandParent.panel.three.Update(x1,y1,lon,lat,vis006)
zx1 = x1 - 0.05
zy1 = y1 - 0.05
zx2 = x1 + 0.05
zy2 = y1 + 0.05
self.rect.set_x(x1 - 0.05) #Move the rectangle and centre it on the X click point
self.rect.set_y(y1 - 0.05) #Move the rectangle and centre it on the Y click point
self.axes.plot()
self.canvas.draw()
global zoom
self.zoom_axes=[zx1,zx2,zy1,zy2]
self.GrandParent.panel.Update(self.zoom_axes)
'self.GrandParent.panel.two.Update(self.zoom_axes)'
class PanelTwo(wx.Panel):
def __init__(self,parent):
super().__init__(parent,name = "PanelTwo",size=(200,200))
def Update(self,parent):
zoom_axes=parent.zoom_axes
#Load axis values of the selected rectangle
self.figure = Figure(figsize =(5,4))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
self.figure.subplots_adjust(left=0.009,right=0.99,bottom=0.09,top=0.99)
self.axes.axis(zoom_axes)
fic='Mmultic3kmNC4_msg04_201905080200.nc'
path='/data/'
#path=''
fic1='/data/latlon_+000.0_globe.nc'
nc = netCDF4.Dataset(path+fic,'r')
IR2 = nc.variables['IR_108'][:]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.IR2 = IR2[:]
self.axes.imshow(self.IR2 ,cmap=plt.cm.gist_yarg)
self.canvas.mpl_connect('button_press_event', self.on_press)
x = y = 0.05
self.rect = patches.Rectangle((x, y), 0.1,0.1,edgecolor='r', alpha=1, fill=None, label='Label')
self.axes.add_patch(self.rect)
self.figure.add_axes(self.axes)
self.axes.plot()
def on_press(self, click):
global x1,y1
x1, y1 = click.xdata, click.ydata
#air_dep seems the wrong way round but what do I know
#The way below gives values that seem correct
IR2 = self.IR2[int(y1),int(x1)]
zx1 = x1 - 0.05
zy1 = y1 - 0.05
zx2 = x1 + 0.05
zy2 = y1 + 0.05
self.rect.set_x(x1 - 0.05) #Move the rectangle and centre it on the X click point
self.rect.set_y(y1 - 0.05) #Move the rectangle and centre it on the Y click point
self.axes.plot()
self.canvas.draw()
global zoom
self.zoom_axes=[zx1,zx2,zy1,zy2]
'self.GrandParent.panel.two.Update(self.zoom_axes)'
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,5))
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='Mmultic3kmNC4_msg04_201905080200.nc'
path='/data/'
#path=''
fic1='/data/latlon_+000.0_globe.nc'
nc = netCDF4.Dataset(path+fic,'r')
IR2 = nc.variables['IR_108'][:]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.IR2 = IR2[:]
self.lons = lons[:]
self.lats = lats[:]
self.lonl = len(self.lons) -1
self.latl = len(self.lats) -1
self.axes.imshow(self.IR2 ,cmap=plt.cm.gist_yarg)
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()
def on_press(self, click):
x1, y1 = click.xdata, click.ydata
#air_dep seems the wrong way round but what do I know
#The way below gives values that seem correct
IR2 = self.IR2[int(y1),int(x1)]
IR2_rect = []
x = int(x1)
y = int(y1)
lon = self.lons[int(y1),int(x1)]
lat = self.lats[int(y1),int(x1)]
# 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:
IR2_rect.append(self.IR2[y-2,x2:x3])
if y-1 < 0:
pass
else:
IR2_rect.append(self.IR2[y-1,x2:x3])
IR2_rect.append(self.IR2[y,x2:x3])
if y+1 > self.latl:
pass
else:
IR2_rect.append(self.IR2[y+1,x2:x3])
if y+2 > self.latl:
pass
else:
IR2_rect.append(self.IR2[y+2,x2:x3])
self.parent.panel_three.Update(x1,y1,IR2,lon,lat,IR2_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()
self.zoom_axes=[zx1,zx2,zy1,zy2]
self.GrandParent.panel.Update(self)
self.GrandParent.panel_two.Update(self)
class PanelThree(wx.Panel): #here when i need to visualize pixel and coordinator cursor
def __init__(self,parent):
wx.Panel.__init__(self,parent,size=(300,350))
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,IR2,lon,lat,IR2_rect):
update_str = "Mouse click at;\nX : "+str(int(x1))+"\nY : "+str(int(y1))+" " +"\nIR : "+ str(int(IR2 - 273.15))+" "+"\nLon : "+str(int(lon))+"\nLat :"+str(int(lat))
self.text_ctrl.SetValue(update_str)
self.text_ctrl.write("\nIR2")
#Table of surrounding temperatures
for i in range(len(IR2_rect)):
s = ""
line = IR2_rect[i]
for i2 in line:
s+="{:5.1f}".format(i2-273.15)+" "
self.text_ctrl.write(s+"\n")
app = wx.App()
frame = MainFrame(None).Show()
app.MainLoop()
hi,i have some Error when i select zoom wirh retangle patch to show it in panel and paneltwo i can see the selection but when i click mouse in panel to mouve it betwen panel and panel two i get error :
File "/home/tm.py", line 126, in on_press self.GrandParent.panel.three.Update(x1,y1,lon,lat,vis006) AttributeError: 'NoneType' object has no attribute 'panel' >>>
how can i fix this error ? to show rectangle in panel&paneltwo in the same time
I'm curious to know what you were expecting. The parent of Panel
is MainFrame. The parent of MainFrame, as you created it in the
next to the last line, is None. Thus, in Panel.on_press,
self.GrandParent will always be None, just as the error says.
Did you intend that Panel be a child of RootPanel? If so, you need to say so, in MainFrame.__init__:
self.root = RootPanel( self )
self.panel = Panel( self.root )
Even after you do that, however, this code still has problems:
self.GrandParent.panel.three.Update( ... )
Let's say you do update the initialization so Panel is a child of RootPanel, which is in turn a child of MainFrame. In that case, MainFrame.panel is just the Panel instance, so that line would be exactly the same as saying:
self.three.Update( ... )
But there is no "three" defined in any of the panels. Was that a typo? Did you mean to say panel_three instead of panel.three? panel_three is a member of RootPanel. So, after you make the change above to have Panel be a child of RootPanel, you would want to use Parent, not GrandParent:
self.Parent.panel_three.Update( ... )
It might be worthwhile for you to draw out a diagram of the parent/child relationships, just to make sure you get the references right.
the second problem that i need to showing the value of variable VIS006 for panel and IR2 for paneltwo in the panelthree the same time when i click in rectangle in panel i can get information about panel and paneltwo in panelthree !
-- Tim Roberts, ti...@probo.com Providenza & Boekelheide, Inc.