title: How to dynamically add an object to a scene in vispy canvas embedded in wxpython
body: <p>I want to add an arrow (some object) upon the press of a button. The code is a modified version of the example given in the vispy repository.</p>
  <pre><code>import wx
  from vispy import scene
  from vispy.scene.visuals import Arrow
  
  import numpy as np
  
  class Canvas(scene.SceneCanvas):
      def __init__(self, *a, **k):
          sizes = k.pop(&quot;sizes&quot;, (300, 300))  # Default value is (300, 300)
          scene.SceneCanvas.__init__(self, *a, **k, size=sizes)
          view = self.central_widget.add_view()
          view.bgcolor = 'snow'
          view.camera = scene.TurntableCamera(up='+y', azimuth=100, elevation=15, fov=60)
          axis = scene.visuals.XYZAxis(parent=view.scene)
          
          arrow1 = np.array([(0, 0, 0, 1, 1, 0)])  # Arrow direction, position
          arr = Arrow(pos=np.array([(0, 0, 0), (1, 1, 0)]), color='teal', method='gl', width=5., arrows=arrow1,
                      arrow_type=&quot;angle_30&quot;, arrow_size=5.0, arrow_color='teal', antialias=True, parent=view.scene)
          
          self.show()
  
  class mainFrame ( wx.Frame ):
  
      def __init__( self, parent ):
          wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = &quot;Add Object&quot;, pos = wx.DefaultPosition, size = wx.Size( 905,569 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
  
          self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
  
          bSizer1 = wx.BoxSizer( wx.VERTICAL )
  
          self.panel_vispy = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
          bSizer1.Add( self.panel_vispy, 9, wx.EXPAND |wx.ALL, 5 )
  
          self.panel_Buttons = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
          bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
  
  
          bSizer2.Add( ( 0, 0), 1, wx.EXPAND, 5 )
  
          self.button_AddArrow = wx.Button( self.panel_Buttons, wx.ID_ANY, u&quot;Add Arrow&quot;, wx.DefaultPosition, wx.DefaultSize, 0 )
          bSizer2.Add( self.button_AddArrow, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
  
  
          bSizer2.Add( ( 0, 0), 1, wx.EXPAND, 5 )
  
  
          self.panel_Buttons.SetSizer( bSizer2 )
          self.panel_Buttons.Layout()
          bSizer2.Fit( self.panel_Buttons )
          bSizer1.Add( self.panel_Buttons, 1, wx.EXPAND |wx.ALL, 5 )
  
  
          self.SetSizer( bSizer1 )
          self.Layout()
  
          self.Centre( wx.BOTH )
          
          # Connect Events
          self.button_AddArrow.Bind(wx.EVT_BUTTON, self.button_AddArrow_OnClick)
          
          self.panel_vispy.canvas = Canvas(app=&quot;wx&quot;, parent=self, sizes=self.panel_vispy.GetSize())
      
      def button_AddArrow_OnClick(self, event):
          print(&quot;Adding arrow&quot;)
          arrow2 = np.array([(0, 0, 0, 1, 1, 0)])  # Arrow direction, position
          arr = Arrow(pos=np.array([(0, 0, 0), (1, 1, 0)]), color='red', method='gl', width=5., arrows=arrow2,
                      arrow_type=&quot;angle_30&quot;, arrow_size=5.0, arrow_color='red', antialias=True)#, parent=view.scene) -Unable to access view from the Canvas class
  
  
  if __name__ == &quot;__main__&quot;:
      app = wx.App(False)
      
      GUI = mainFrame(None)
      
      GUI.Show(True)
      
      app.MainLoop()
  </code></pre>
  <p>I have created the Canvas as given in the example and tried to instantiate it from the <code>mainFrame</code>. All the objects that are given in the <code>__init__</code>  of the <code>Canvas</code> class are created. If I want to add any new object after the GUI is created with the press of a button, I am unable to access the <code>view</code> in the <code>Canvas</code> class from the <code>mainFrame</code>. Or is there any other way to achieve this.</p>
  <p><strong>Update:</strong>
  Here is the code after following the suggestions given in the comments:</p>
  <pre><code>import wx
  from vispy import scene, gloo
  from vispy.scene.visuals import Arrow
  
  import numpy as np
  
  class Canvas(scene.SceneCanvas):
      def __init__(self, *a, **k):
          sizes = k.pop(&quot;sizes&quot;, (300, 300))  # Default value is (300, 300)
          scene.SceneCanvas.__init__(self, *a, **k, size=sizes)
          self.unfreeze()
          self.view = self.central_widget.add_view()
          self.view.bgcolor = 'snow'
          self.view.camera = scene.TurntableCamera(up='+y', azimuth=100, elevation=15, fov=60)
          axis = scene.visuals.XYZAxis(parent=self.view.scene)
          
          arrow1 = np.array([(0, 0, 0, 1, 1, 0)])  # Arrow direction, position
          arr = Arrow(pos=np.array([(0, 0, 0), (1, 1, 0)]), color='teal', method='gl', width=5., arrows=arrow1,
                      arrow_type=&quot;angle_30&quot;, arrow_size=5.0, arrow_color='teal', antialias=True, parent=self.view.scene)
          
          self.show()
      
  class mainFrame ( wx.Frame ):
  
      def __init__( self, parent ):
          wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = &quot;Add Object&quot;, pos = wx.DefaultPosition, size = wx.Size( 905,569 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
  
          self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
  
          bSizer1 = wx.BoxSizer( wx.VERTICAL )
  
          self.panel_vispy = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
          bSizer1.Add( self.panel_vispy, 9, wx.EXPAND |wx.ALL, 5 )
  
          self.panel_Buttons = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
          bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
  
  
          bSizer2.Add( ( 0, 0), 1, wx.EXPAND, 5 )
  
          self.button_AddArrow = wx.Button( self.panel_Buttons, wx.ID_ANY, u&quot;Add Arrow&quot;, wx.DefaultPosition, wx.DefaultSize, 0 )
          bSizer2.Add( self.button_AddArrow, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
  
  
          bSizer2.Add( ( 0, 0), 1, wx.EXPAND, 5 )
  
  
          self.panel_Buttons.SetSizer( bSizer2 )
          self.panel_Buttons.Layout()
          bSizer2.Fit( self.panel_Buttons )
          bSizer1.Add( self.panel_Buttons, 1, wx.EXPAND |wx.ALL, 5 )
  
  
          self.SetSizer( bSizer1 )
          self.Layout()
  
          self.Centre( wx.BOTH )
          
          # Connect Events
          self.button_AddArrow.Bind(wx.EVT_BUTTON, self.button_AddArrow_OnClick)
          
          self.panel_vispy.canvas = Canvas(app=&quot;wx&quot;, parent=self, sizes=self.panel_vispy.GetSize())
      
      def button_AddArrow_OnClick(self, event):
          print(&quot;Adding arrow&quot;)
          arrow2 = np.array([(0, 0, 0, 1, 1, 0)])  # Arrow direction, position
          arr = Arrow(pos=np.array([(0, 0, 0), (1, 1, 0)]), color='teal', method='gl', width=5., arrows=arrow2,
                      arrow_type=&quot;angle_30&quot;, arrow_size=5.0, arrow_color='teal', antialias=True, parent=self.panel_vispy.canvas.view.scene)
          self.panel_vispy.canvas.update() # Canvas not getting updated
  
  
  if __name__ == &quot;__main__&quot;:
      app = wx.App(False)
      
      GUI = mainFrame(None)
      
      GUI.Show(True)
      
      app.MainLoop()
  </code></pre>
  <p>The code now runs without any error which means the arrow is probably added but the scene is not updated.</p>