import wx
import numpy as np
import netCDF4
import os
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 """
fram=None
index=None
def __init__(self, parent):
super().__init__(parent,size = (800,650))
global index
index=1
self.root = RootPanel(self)
self.bottom = BottomPanel(self)
sizer= wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.root, 1, wx.EXPAND)
sizer.Add(self.bottom, 1, wx.EXPAND)
self.SetSizer(sizer)
global fram
fram=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_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 BottomPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent, name="Left", style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('gray')
dynamic=wx.Button(self,-1,"Dynamic",size=(110,30),pos=(0,10))
self.Bind(wx.EVT_BUTTON, self.newwindow, dynamic)
variable =wx.Button(self,-1,"Variable ",size=(80,30),pos=(0,50))
variable.Bind(wx.EVT_BUTTON, self.ShowPopup_var)
def ShowPopup_var(self, event):
popmenu = wx.Menu()
visible = wx.Menu()
visible.Append( -1, "VIS006")
visible.Append( -1, "VIS008")
popmenu.Append( -1, "visible", visible)
infrared = wx.Menu()
infrared.Append( -1, "IR039")
infrared.Append( -1, "WV073")
infrared.Append( -1, "IR108")
infrared.Append( -1, "IR120")
infrared.Append( -1, "IR134")
infrared.Append( -1, "IR087")
infrared.Append( -1, "IR062")
infrared.Append( -1, "IR097")
popmenu.Append( -1, "infrared", infrared)
self.Bind(wx.EVT_MENU, self.OnChoice)
self.PopupMenu(popmenu)
popmenu.Destroy()
def OnChoice(self, event):
id = event.GetId()
obj = event.GetEventObject()
data_list = ['VIS006','VIS008','IR120','IR108','IR087','IR134','IR039','WV073','IR062','IR097']
global index
index=data_list.index(obj.GetLabelText(id))
print("Option chosen",obj.GetLabelText(id))
print("Option chosen id",id)
'self.foo.objetparent.destory()'
'self.foo.objetparent = CanvasPanel(self.foo.objetparent)'
'print("self.foo.objetparent ",self.foo.objetparent)'
'self.foo.objetparent.Update()'
'self.foo.objetparent.Refresh()'
def newwindow(self, event):
secondWindow = window2(parent=self)
secondWindow.Show()
class window2(wx.Frame):
title = "new Window"
def __init__(self,parent):
"""
This is similar to the class MainFrame. You define a parent wx.Panel
and all other widgets are his childs.
"""
wx.Frame.__init__(self,parent, -1,'Dynamic of image', size=(300,100))
self.panel=wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
self.st = wx.StaticText(self.panel, label='Edit Dynamic', style=wx.ALIGN_CENTER)
self.text = wx.TextCtrl(self.panel, size=(200, 20), style=wx.SUNKEN_BORDER|wx.TE_PROCESS_ENTER)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.st, 0, wx.EXPAND|wx.ALL, 5)
self.sizer.Add(self.text, 0, wx.ALIGN_CENTER|wx.ALL, 5)
self.panel.SetSizer(self.sizer)
self.sizer.Fit(self.panel)
self.Centre()
self.Show()
self.Bind(wx.EVT_TEXT_ENTER, self.onEnter)
def onEnter(self, event):
print(self.text.GetValue())
self.Destroy()
class PickButton(wx.Button):
""" Bouton permettant de choisir un fichier """
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):
""" 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):
def __init__(self, parent , name = 'CanvasPanel', 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):
global file_names
file_names=file_name
path=file_name
self.file_name=file_name
nc = netCDF4.Dataset(file_name)
fic1='D:/data/latlon_+000.0_globe.nc'
nc1 = netCDF4.Dataset(fic1,'r')
keys = nc.variables.keys()
list_var = [nc.variables['VIS006'],nc.variables['IR_120'],nc.variables['IR_108'],nc.variables['IR_087'],nc.variables['IR_134'],nc.variables['IR_039'],nc.variables['WV_073']]
print("update")
data_list = ['VIS006','IR_120','IR_108','IR_087','IR_134','IR_039','WV_073']
list_var = [nc.variables[f] for f in data_list]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.lons = lons[:]
self.lats = lats[:]
self.lonl = len(self.lons) -1
self.latl = len(self.lats) -1
print("Option chosen update")
global index
print("index=",index)
self.list_var = list_var[index][:]
self.axes.imshow(self.list_var ,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.figure.add_axes(self.axes)
'self.figure.show()'
self.axes.plot()
'self.GrandParent.canvas_panel.Update(self)'
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
list_var = self.list_var[int(y1),int(x1)]
list_var_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:
list_var_rect.append(self.list_var[y-2,x2:x3])
if y-1 < 0:
pass
else:
list_var_rect.append(self.list_var[y-1,x2:x3])
list_var_rect.append(self.list_var[y,x2:x3])
if y+1 > self.latl:
pass
else:
list_var_rect.append(self.list_var[y+1,x2:x3])
if y+2 > self.latl:
pass
else:
list_var_rect.append(self.list_var[y+2,x2:x3])
self.Parent.panel_three.Update(x1,y1,list_var,lon,lat,list_var_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 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,list_var,lon,lat,list_var_rect):
update_str = "Mouse click at;\nX : "+str(int(x1))+"\nY : "+str(int(y1))+" " +"\nlist_var : "+ str(int(list_var - 273.15))+" "+"\nLon : "+str(lon)+"\nLat :"+str(lat)
self.text_ctrl.SetValue(update_str)
self.text_ctrl.write("\n list-var \n")
#Table of surrounding temperatures
for i in range(len(list_var_rect)):
s = ""
line = list_var_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()
You can also „trick“ around messaging between the panels by, i.e. have the graph poll the state of the button or the bitmap of the button and „refresh itself“ when the button was pressed. Or you use a txt file or nosql database in which you store the button state or time or ... Anyway, this is just simplified workarounds- you are better off cleaning your code a little anyways - see Tim‘s post. Cheers