3

I've been looking for a while for a means of fast plotting of large heatmap in a python based UI. In the past, I have used the backends available for matplotlib ' contourf, pcolor, and pcolormesh. I have not used imshow as my typical data lies on a polar plane (radar). In matplotlib I would the following

from matplotlib import Figure
import numpy as np

# some class initialization 
        self.fig = Figure ()
        self.axes = self.fig.add_subplot (111, polar=True)

    def plotter (self):
        self.axes.cla ()
        self.axes.pcolormesh (self.thetas, self.ranges, self.data)
        self.axes.draw ()

I've been investigating the OPENGL libraries, and I like the gentle introduction that I've witnessed with vispy. At the end of the day, I would like to find the simplest means to define a set of 2D vertexes and be able to vary the color associated with them, and fill the pixels inbetween; either in a linear gradient or solid polygon way. While I don't fully grasp textures, I can invision defining many triangles and their colors, but this seems inefficient. There must be a straightforward means to define points and their colors, and fill in between.

Something like

from vispy import gloo, app
app.use_app('pyside')
import numpy as np

VERTEX = '''
attribute vec2 position;
attribute vec4 color;
varying vec4 v_color;
void main() {
    v_color = color;
    gl_Position = vec4(position, 0.0, 1.0);
}
'''

FRAGMENT = '''
varying vec4 v_color
void main() {
// magic
}
'''

class PolarHeatmapWidget(app.Canvas):
    def __init__(self,_Ntheta,_Nr, **kwargs):
        app.Canvas.__init__(self, size=(400,400), **kwargs)
        self.Ntheta = _Ntheta
        self.Nr = _Nr
        self.program = gloo.Program (VERTEX, FRAGMENT)
        self.initializeData()
        self.program ['position'] = gloo.VertexBuffer(self.positions)
        self.program ['color'] = gloo.VertexBuffer(self.colors)
        self.apply_zoom()        

    def on_draw(self, event):
        gloo.clear()
        self.program.draw(MORE_MAGIC)

    def intialize(self):
        self.show()

    def on_resize(self, event):
        self.apply_zoom()

    def apply_zoom(self):
        minsize = min(self.physical_size[0], self.physical_size[1])
        gloo.set_viewport(self.physical_size[0] / 2 - minsize / 2, \
                          self.physical_size[1] / 2 - minsize / 2, \
                          minsize, minsize)
        self.update()

    def initializeData(self):
       ranges = np.linspace(0,1,self.Nr)
       thetas = np.radians(np.linspace(0,360,self.Ntheta))
       self.positions = np.zeros((self.Ntheta*self.Nr, 2), dtype=np.float32)
       for t in xrange(self.Ntheta):
           for r in xrange(self.Nr):
               self.positions[t*self.Nr+r][0] = ranges[r] * np.cos(thetas[t])
               self.positions[t*self.Nr+r][1] = ranges[r] * np.sin(thetas[t])
       self.colors = np.zeros((self.Ntheta*self.Nr, 4), dtype=np.float32)
       self.colors[:,3] += 1

I apologize for the brief code - from a phone but my goal is to end up with a full class in this thread to help myself and others involved in data science understand graphics at a lower level to accelerate rendering.

Thanks in advance and my apologies if I've missed something obvious in documentation.

johnnymopo
  • 158
  • 9
  • I will follow up with a working example soon, I think an example of the shaders to use can be found in pyheat https://github.com/amccollum/pyheat/blob/master/pyheat/heatmap.py – johnnymopo Oct 31 '15 at 05:04

0 Answers0