docs: def redraw(self, col=0):
          """redraw image, applying the following:
          rotation, flips, log scale
          max/min values from sliders or explicit intensity ranges
          color map
          interpolation
          """
          conf = self.conf
          # note: rotation re-calls display(), to reset the image
          # other transformations will just do .set_data() on image
          if conf.rot:
              if self.xdata is not None:
                  self.xdata = self.xdata[::-1]
              if self.ydata is not None:
                  self.ydata = self.ydata[:]
  
              self.display(np.rot90(conf.data),
                           x=self.ydata, xlabel=self.ylab,
                           y=self.xdata, ylabel=self.xlab)
          # flips, log scales
          img = conf.data
          if img is None: return
          if len(img.shape) == 2:
              col = 0
          if self.conf.style == 'image':
              if conf.flip_ud:   img = np.flipud(img)
              if conf.flip_lr:   img = np.fliplr(img)
              if conf.log_scale:
                  img = np.log10(1 + 9.0*img)
  
          # apply intensity scale for current limited (zoomed) image
          if len(img.shape) == 2:
              # apply clipped color scale, as from sliders
  
              imin = float(conf.int_lo[col])
              imax = float(conf.int_hi[col])
              if conf.log_scale:
                  imin = np.log10(1 + 9.0*imin)
                  imax = np.log10(1 + 9.0*imax)
  
              (xmin, xmax, ymin, ymax) = self.conf.datalimits
              if xmin is None:  xmin = 0
              if xmax is None:  xmax = img.shape[1]
              if ymin is None:  ymin = 0
              if ymax is None:  ymax = img.shape[0]
  
  
              img = (img - imin)/(imax - imin + 1.e-8)
              mlo = conf.cmap_lo[0]/(1.0*conf.cmap_range)
              mhi = conf.cmap_hi[0]/(1.0*conf.cmap_range)
              if self.conf.style == 'image':
                  conf.image.set_data(np.clip((img - mlo)/(mhi - mlo + 1.e-8), 0, 1))
                  conf.image.set_interpolation(conf.interp)
          else:
              r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]
  
              rmin = float(conf.int_lo[0])
              rmax = float(conf.int_hi[0])
              gmin = float(conf.int_lo[1])
              gmax = float(conf.int_hi[1])
              bmin = float(conf.int_lo[2])
              bmax = float(conf.int_hi[2])
              if conf.log_scale:
                  rmin = np.log10(1 + 9.0*rmin)
                  rmax = np.log10(1 + 9.0*rmax)
                  gmin = np.log10(1 + 9.0*gmin)
                  gmax = np.log10(1 + 9.0*gmax)
                  bmin = np.log10(1 + 9.0*bmin)
                  bmax = np.log10(1 + 9.0*bmax)
  
              rlo = conf.cmap_lo[0]/(1.0*conf.cmap_range)
              rhi = conf.cmap_hi[0]/(1.0*conf.cmap_range)
              glo = conf.cmap_lo[1]/(1.0*conf.cmap_range)
              ghi = conf.cmap_hi[1]/(1.0*conf.cmap_range)
              blo = conf.cmap_lo[2]/(1.0*conf.cmap_range)
              bhi = conf.cmap_hi[2]/(1.0*conf.cmap_range)
              r = (r - rmin)/(rmax - rmin + 1.e-8)
              g = (g - gmin)/(gmax - gmin + 1.e-8)
              b = (b - bmin)/(bmax - bmin + 1.e-8)
  
              inew = img*1.0
              inew[:,:,0] = np.clip((r - rlo)/(rhi - rlo + 1.e-8), 0, 1)
              inew[:,:,1] = np.clip((g - glo)/(ghi - glo + 1.e-8), 0, 1)
              inew[:,:,2] = np.clip((b - blo)/(bhi - blo + 1.e-8), 0, 1)
  
              whitebg = conf.tricolor_bg.startswith('wh')
  
              if whitebg:
                  inew = conf.tricolor_white_bg(inew)
  
              if self.conf.style == 'image':
                  conf.image.set_data(inew)
                  conf.image.set_interpolation(conf.interp)
          self.canvas.draw()
          if callable(self.redraw_callback):
              self.redraw_callback(wid=self.GetId())