code: def render(self):
      self._context = "run"
      # Clear output
      if "inline" in self.backend:
          IPython.display.clear_output(wait=True)
          self.figure = None
  
      # Separate the draw_*() calls that generate a grid cell
      grid_calls = []
      silent_calls = []
      for c in self.drawing_calls:
          if c[0] == "draw_summary":
              silent_calls.append(c)
          else:
              grid_calls.append(c)
  
      # Header area
      # TODO: ideally, compute how much header area we need based on the
      #       length of text to show there. Right now, we're just using
      #       a fixed number multiplied by the number of calls. Since there
      #       is only one silent call, draw_summary(), then the header padding
      #       is either 0 or 0.1
      head_pad = 0.1 * len(silent_calls)
  
      width = self.theme["fig_width"]
      if not self.figure:
          self.figure = plt.figure(
              figsize=(width, width / 3 * (head_pad + len(grid_calls)))
          )
      self.figure.clear()
  
      # Divide figure area by number of grid calls
      gs = matplotlib.gridspec.GridSpec(len(grid_calls), 1)
  
      # Call silent calls
      for c in silent_calls:
          getattr(self, c[0])(*c[1], **c[2])
  
      # Call grid methods
      for i, c in enumerate(grid_calls):
          method = c[0]
          # Create an axis for each call
          # Save in in self.ax so the drawing function has access to it
          self.ax = self.figure.add_subplot(gs[i])
          # Save the GridSpec as well
          self.gs = gs[i]
          # Call the method
          getattr(self, method)(*c[1], **c[2])
      # Cleanup after drawing
      self.ax = None
      self.gs = None
      gs.tight_layout(self.figure, rect=(0, 0, 1, 1 - head_pad))
  
      # TODO: pause() allows the GUI to render but it's sluggish because it
      # only has 0.1 seconds of CPU time at each step. A better solution would be to
      # launch a separate process to render the GUI and pipe data to it.
      plt.pause(0.1)
      plt.show(block=False)
      self.drawing_calls = []
      self._context = None
  
imports: import itertools
  import math
  import numpy
  import matplotlib
  import matplotlib.pyplot
  import IPython.display
  from mpl_toolkits.mplot3d import Axes3D
  from matplotlib.collections import PolyCollection
label_desc: Use image node_id 4 for calling the Canvas obj's underlying member method code with example usage: obj.render() without return types