在矩形类缩放中选择区域时出错(wx.frame) [英] error when select area inside rectangle class zoom(wx.frame)
问题描述
在对矩形选择器内的绘图区域有一些帮助后,我工作了,但是当我在某些代码应用程序中应用时,我遇到了如下错误:
after have some help about plot area inside rectangle selector i worked but when i applicated in some code app i have error like :
Traceback (most recent call last):
File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\cbook\__init__.py", line 215, in process
func(*args, **kwargs)
File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\widgets.py", line 1597, in release
self._release(event)
File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\widgets.py", line 2194, in _release
self.onselect(self.eventpress, self.eventrelease)
TypeError: line_select_callback() missing 1 required positional argument: 'erelease'
我不知道为什么它不能在我的应用程序中运行类(缩放)一切都很好,但我不知道代码中的问题在哪里.
i don't know why it can't working the class(zoom) in my app all is good i thing but i dont know where is the problem inside code .
当我需要在矩形内选择区域时,这是第二个应用程序的代码:
this is code for second application when i need to do the select area inside rectangle :
import wx
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
import matplotlib
import matplotlib.pyplot as plt
import os
class MainFrame(wx.Frame):
def __init__(self, parent ):
super().__init__(parent,title= "quick",size = (2000,1000))
left = LeftPanel(self)
middle = MiddlePanel(self)
right = RightPanel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(left, 3, wx.EXPAND)
sizer.Add(middle, 5, wx.EXPAND)
sizer.Add(right, 5, wx.EXPAND)
self.SetSizer(sizer)
# ------------ LEFT ------------
class LeftPanelTop(wx.Panel):
def __init__(self, parent,size = (610,350)):
super().__init__(parent)
self.figure = Figure(figsize =(5,3))
self.canvas = FigureCanvas(self, -1, self.figure)
self.Size = self.canvas.Size
self.zoom_axes = []
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_nc(self, file_name):
""" Simule le chargement et affichage à partir d'un fichier nc """
t = np.arange(0.0, 8.0, 0.01)
s = np.sin(3 * np.pi * t)
self.axes.plot(t, s)
self.RS = RectangleSelector(self.axes,line_select_callback,
drawtype='box', useblit=False,
button=[1, 3],minspanx=5, minspany=5,
spancoords='pixels',
interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
def line_select_callback(self,eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
self.zoom_axis=[x1,x2,y1,y2]
Zoom(parent=self)
class Zoom(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,-1,("Zoom"))
self.parent
#Make this zoom window self cancelling if it loses focus
self.Bind(wx.EVT_ACTIVATE, self.OnExit)
#Load axis values of the selected rectangle
zoom_axis=parent.zoom_axis
#duplicate the plot from the main panel
self.figure = Figure(figsize =(5,6))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
""" Simule le chargement et affichage à partir d'un fichier nc """
t = np.arange(0.0, 8.0, 0.01)
s = np.sin(3 * np.pi * t)
#Apply axis of drawn rectangle to the plot
self.axes.axis(zoom_axis)
self.axes.pcolormesh(air_dep,cmap=plt.get_cmap('binary'))
self.canvas.draw()
self.show()
def OnExit(self, event):
focus = event.GetActive()
if focus == True : # Window lost focus
self.Close()
class LeftPanelBottom(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER,size = (510,450) )
self.SetBackgroundColour('snow2')
panel_buttons = wx.Panel(self)
canvas_panel = LeftPanelTop(self)
panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)
select_button = PickButton(
panel_buttons,
"netCDF4 files (nc)|*.nc",
canvas_panel.load_from_file,
label="Open file",)
panel_buttons_sizer.Add(select_button)
panel_buttons.SetSizer(panel_buttons_sizer)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel_buttons)
sizer.Add(canvas_panel)
self.SetSizer(sizer)
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 = 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 LeftPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
top = LeftPanelTop(self)
bottom = LeftPanelBottom(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(top, 3, wx.EXPAND)
sizer.Add(bottom, 4, wx.EXPAND)
self.SetSizer(sizer)
# ------------ MIDDLE ------------
class MiddlePanelTop(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('black')
canal=wx.Button(self,-1,label ="Variable",size=(140,30),pos=(100,0))
dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
dynamique.SetBackgroundColour('white')
canal.SetBackgroundColour('white')
file.SetBackgroundColour('white')
dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
file.Bind(wx.EVT_BUTTON, self.onOpen)
def onOpen(self, event):
wildcard = "netCDF4 files (*.nc)|*.nc"
dialog = wx.FileDialog(self, "Open netCDF4 Files", wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dialog.ShowModal() == wx.ID_CANCEL:
return
path = dialog.GetPath()
if os.path.exists(path):
with open(path) as fobj:
for line in fobj:
self.my_text.WriteText(line)
def OnClick(self,event):
dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image')
if dlg.ShowModal() == wx.ID_OK:
self.text.SetValue("Dynamique:"+dlg.GetValue())
dlg.Destroy()
class MiddlePanelBottom(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('black')
canal=wx.Button(self,-1,"Variable",size=(140,30),pos=(100,0))
dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
dynamique.SetBackgroundColour('white')
canal.SetBackgroundColour('white')
file.SetBackgroundColour('white')
dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
file.Bind(wx.EVT_BUTTON, self.onOpen)
self.load_options = "netCDF4 files (nc)|*.nc| Text files (txt) |*.txt| All files |*.*"
def onOpen(self, event):
wildcard = "netCDF4 files (*.nc)|*.nc"
dialog = wx.FileDialog(self, "Open netCDF4 Files", wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dialog.ShowModal() == wx.ID_CANCEL:
return
path = dialog.GetPath()
if os.path.exists(path):
with open(path) as fobj:
for line in fobj:
self.my_text.WriteText(line)
def OnClick(self,event):
dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image')
if dlg.ShowModal() == wx.ID_OK:
self.text.SetValue("Dynamique:"+dlg.GetValue())
dlg.Destroy()
class MiddlePanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
top = MiddlePanelTop(self)
bottom = MiddlePanelBottom(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(top, 2, wx.EXPAND)
sizer.Add(bottom, 2, wx.EXPAND)
self.SetSizer(sizer)
# ------------ RIGHT ------------
class RightPanelTop(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour('black')
canal=wx.Button(self,-1,"Variable",size=(140,30),pos=(100,0))
dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
dynamique.SetBackgroundColour('white')
canal.SetBackgroundColour('white')
file.SetBackgroundColour('white')
dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
file.Bind(wx.EVT_BUTTON, self.onOpen)
def onOpen(self, event):
wildcard = "netCDF4 files (*.nc)|*.nc| HDF5 files (*.h5) |*.h5"
dialog = wx.FileDialog(self, "Open netCDF4 Files| HDF5 files", wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dialog.ShowModal() == wx.ID_CANCEL:
return
path = dialog.GetPath()
if os.path.exists(path):
with open(path) as fobj:
for line in fobj:
self.my_text.WriteText(line)
def OnClick(self,event):
dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image')
if dlg.ShowModal() == wx.ID_OK:
self.text.SetValue("Dynamique:"+dlg.GetValue())
dlg.Destroy()
class RightPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
top = RightPanelTop(self)
bottom = RightPanelBottom(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(top, 2, wx.EXPAND)
sizer.Add(bottom, 2, wx.EXPAND)
self.SetSizer(sizer)
class PanelBottom(wx.Panel):
def __init__(self,parent):
super().__init__(parent)
self.SetBackgroundColour('grey77')
class PanelTop(wx.Panel):
def __init__(self,parent):
super().__init__(parent)
left = SubPanelLeft(self)
right = SubPanelRight(self)
midlle = SubPanelMiddle(self)
sizer1 = wx.BoxSizer(wx.HORIZONTAL)
sizer1.Add(left, 1, wx.EXPAND)
sizer1.Add(midlle, 1, wx.EXPAND)
sizer1.Add(right, 1, wx.EXPAND)
self.SetSizer(sizer1)
class RightPanelBottom(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour('snow2')
top = PanelTop(self)
bottom = PanelBottom(self)
sizer1 = wx.BoxSizer(wx.VERTICAL)
sizer1.Add(top, 2, wx.EXPAND)
sizer1.Add(bottom, 4, wx.EXPAND)
self.SetSizer(sizer1)
class SubPanelLeft(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('black')
class SubPanelMiddle(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('black')
class SubPanelRight(wx.Panel):
def __init__(self, parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.SetBackgroundColour('black')
app = wx.App()
frame = MainFrame(None).Show()
app.MainLoop()
推荐答案
要重新安排代码中的内容,以使用 panel
而不是新的 frame
.虽然,只有在程序用户需要时才创建一个新框架,而现有的 panel
必须存在,无论是否需要!
It's a matter of rearranging things within the code to use a panel
rather than a new frame
. Although, a new frame is only created as needed by the user of the program, whilst an existing panel
has to be there, whether it is needed or not!
我已经重新排列了先前的答案,以在另一个面板中显示 zoom
,但是出于我的一生,我不明白为什么您不利用内置的使用
工具栏. NavigationToolbar2Wx
的matplotlib
I've rearranged a previous answer to show the zoom
in another panel but for the life of me, I don't understand why you don't take advantage of the built in matplotlib
toolbar using NavigationToolbar2Wx
.
import wx
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
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.zoom_panel = Zoom(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.zoom_panel,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 =(4,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 """
N = 100000
x = np.linspace(0.0, 10.0, N)
self.axes.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)
self.axes.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
self.axes.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)
self.RS = RectangleSelector(self.axes,self.line_select_callback,
drawtype='box', useblit=True,
button=[1, 3],minspanx=5, minspany=5,
spancoords='pixels',
interactive=True,
rectprops = dict(facecolor='None',edgecolor='red',alpha=0.5,fill=False))
def line_select_callback(self, eclick, erelease):
'eclick and erelease are the press and release events'
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
self.zoom_axes=[x1,x2,y1,y2]
self.parent.zoom_panel.Update(self)
class Zoom(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent,size=(200,250))
self.Show()
def Update(self,parent):
#Load axis values of the selected rectangle
zoom_axes=parent.zoom_axes
#duplicate the plot from the main panel
self.figure = Figure(figsize =(4,3))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
#Apply axis of drawn rectangle to the plot
self.axes.axis(zoom_axes)
N = 100000
x = np.linspace(0.0, 10.0, N)
self.axes.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)
self.axes.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
self.axes.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)
self.canvas.draw()
self.Refresh()
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()
这篇关于在矩形类缩放中选择区域时出错(wx.frame)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!