Easysvg is a nice little wrapper to make svg files. Unzip and put in the gateway’s user-lib/pylib/site-packages folder.
easysvg.zip (6.7 KB)
View attached using the csv data posted. The SVG can be converted to base64 to display in an image component.
heatmap_test.zip (76.0 KB)
Script:
import easysvg
import base64
class heatPalette:
'''
Calculate the RGB value of a point on a gradient.
Usage: heatPalette(minval, maxval, [colors])
minval - minimun value to scale to
maxval - maximum value to scale to
colors - A list of RGB colors delineating a series of
adjacent linear color gradients between each pair.
Example: scale the values between 20 and 35 to a three color gradient.
p = heatPalette(20, 35, ['#0000FF', '#FFFF00', '#FF0000'])
After the instance is created, call it with a value to get the scaled color
p(20) returns '#0000FF'
p(25) returns '#AAAA55'
'''
def __init__(self, minval, maxval, colors):
self.minval = minval
self.maxval = maxval
self.colors = []
for color in colors:
if type(color).__name__ == 'str':
c = self.hex_to_rgb(color)
elif type(color).__name__ == 'list':
c = tuple(color)
elif type(color).__name__ == 'tuple':
c = color
self.colors.append(c)
def __call__(self, value):
return self.calc(value)
def calc(self, value):
import sys
# Smallest possible difference.
epsilon = sys.float_info.epsilon
# Keep value within limits
if value < self.minval:
value = self.minval
if value > self.maxval:
value = self.maxval
'''
Determine where the given value falls proportionality within
the range from minval->maxval and scale that fractional value
by the total number in the "colors" pallette.
'''
i_f = float(value-self.minval) / float(self.maxval-self.minval) * (len(self.colors)-1)
'''
Determine the lower index of the pair of color indices this
value corresponds and its fractional distance between the lower
and the upper colors.
'''
# Split into integer & fractional parts.
i, f = int(i_f // 1), i_f % 1
# Does it fall exactly on one of the color points?
if f < epsilon:
return self.rgb_to_hex(self.colors[i])
# Otherwise return a color within the range between them.
else:
(r1, g1, b1), (r2, g2, b2) = self.colors[i], self.colors[i+1]
print (r1, g1, b1), (r2, g2, b2)
print int(r1 + f*(r2-r1)), int(g1 + f*(g2-g1)), int(b1 + f*(b2-b1))
return self.rgb_to_hex((int(r1 + f*(r2-r1)), int(g1 + f*(g2-g1)), int(b1 + f*(b2-b1))))
def hex_to_rgb(self, value):
'''
Convert a hex RGB value to a tuple of 0-255 values
'''
value = value.lstrip('#')
return tuple(int(value[i:i+2], 16) for i in (0, 2, 4))
def rgb_to_hex(self, rgb):
'''
Convert an RGB tuple to a hex string
'''
return '#%02x%02x%02x' % rgb
# Define palette for heatmap
palette = heatPalette(20, 35, ['#0000FF', '#FFFF00', '#FF0000'])
# Width, Height of each cell in heatmap
cellSize = (30, 30)
# Define padding area aroung the heatmap
padding = 50
# Create SVG
svg = easysvg.SvgGenerator()
svg.begin(cellSize[0] * (dataIn.columnCount - 2) + 2 * padding, cellSize[1] * dataIn.rowCount + 2* padding)
for i, row in enumerate(dataIn):
for j, col in enumerate(list(row)[2:]):
color = palette(col)
svg.rect(j*cellSize[0] + padding, i * cellSize[1] + padding, cellSize[0], cellSize[1], color)
#svg.text('This is text', 20, 20)
#svg.circle(75, 75, 50, '#ff0000')
#svg.rect(150, 150, 50, 75, '#ff0000')
svg.end()
svg_string = svg.get_svg()
b64 = base64.b64encode(svg_string)
self.getSibling("Image").props.source = 'data:image/svg+xml;base64,' + b64