title: How to plot many 3D cubes with different colors and opacities
body: <h2>Goal</h2>
  <p>I want to plot a large number of cubes (arranged in a 3D grid) with different colors and opacities.</p>
  <h2>Current State and question</h2>
  <p>I have come up with a solution using <code>vispy</code>, but the performance is very poor - drawing takes very long and the window is very unresponsive. Also, there seem to be some glitches in the visualization, but I could live with those.</p>
  <p>Is there a more efficient/elegant way to implement that? I am open to using other packages (I have tried <code>open3d</code> but found it difficult to specify colors and opacities - the documentation is not very verbose). However, I need to use python.</p>
  <h2>What I did so far</h2>
  <p>The first problem I had to solve with <code>vispy</code> was that I was unable to create cubes at custom positions. I therefore wrote a subclass that can do that:</p>
  <pre><code>import vispy.visuals
  from vispy.geometry import create_box
  
  class PositionedCubeVisual(vispy.visuals.BoxVisual):
      
      def __init__(self, size=1, position=(0, 0, 0), width_segments=1,
                   height_segments=1, depth_segments=1, planes=None,
                   vertex_colors=None, face_colors=None,
                   color=(0.5, 0.5, 1, 1), edge_color=None, **kwargs):
          
          vertices, filled_indices, outline_indices = create_box(
              size, size, size, width_segments, height_segments,
              depth_segments, planes)
          
          for column, pos in zip(vertices['position'].T, position):
              column += pos
          
          self._mesh = vispy.visuals.MeshVisual(vertices['position'], filled_indices,
                                  vertex_colors, face_colors, color)
          if edge_color:
              self._border = vispy.visuals.MeshVisual(vertices['position'], outline_indices,
                                        color=edge_color, mode='lines')
          else:
              self._border = vispy.visuals.MeshVisual()
  
          vispy.visuals.CompoundVisual.__init__(self, [self._mesh, self._border], **kwargs)
          self.mesh.set_gl_state(polygon_offset_fill=True,
                                 polygon_offset=(1, 1), depth_test=True)
          
  PositionedCube = vispy.scene.visuals.create_visual_node(PositionedCubeVisual)
  </code></pre>
  <p>I then plot the cubes as follows:</p>
  <pre><code>import numpy as np
  import vispy.scene
  
  def plot_grid_cubes(x, y, z, c=None, size=1, alpha=0.1, edge_color=&quot;black&quot;, 
                      cmap=&quot;viridis&quot;, bgcolor=&quot;#FFFFFF&quot;):
      
      canvas = vispy.scene.SceneCanvas(keys='interactive', show=True)
      
      view = canvas.central_widget.add_view()
      view.bgcolor = bgcolor
      view.camera = 'turntable'
      
      c = get_color_array(c, alpha, min(len(x), len(y), len(z)), cmap)
      
      for xx, yy, zz, cc in zip(x, y, z, c):
          
          cube = PositionedCube(size, (xx, yy, zz), color=cc, edge_color=edge_color, parent=view.scene)
      
      canvas.app.run()
  
  
  def get_color_array(c, alpha, size, cmap):
      if c is not None:
          cmap = cm.get_cmap(cmap)
          if hasattr(c, &quot;__iter__&quot;):
              c = np.array(c, copy=True, dtype=float)
              c -= c.min() 
              c *= 255/c.max()
          return cmap(c.astype(int), alpha)
      else:
          color = np.ones((size, 4))
          color[:, 3] = alpha
          return color
  
  </code></pre>
  <p>This can then be applied as follows:</p>
  <pre><code>plot_grid_cubes([0, 1], [0, 1], [0, 1], c=[0.3, 0.5], alpha=[0.3, 0.8])
  </code></pre>
  <p>The example above works great, but it becomes poor if I plot thousands of cubes.</p>