# Gauges and Meters - Multiple Vert/Horiz Meter.

Gauges and Meters - Multiple Vert/Horiz Meter.
Hello,

A few posts back, I included source code to some gauges I had whipped together. After some constructive advice from John Hunter (Thanks!), I’ve had time to polish them a bit and include the logarithmic ones as promised.

···

===============================================================================

#!/usr/bin/env python

“”"

The Meter widget draws a linear meter, either horizontally or vertically. You supply the direction, limits,

shaded regions, names and the current value, and invoke it like this:

``````from pylab import figure, show

raw_value = -4.0

raw_limits = [-10.0,10.0,5,1]

raw_zones = [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]

attribute_name = "Rx MOS (24h)"

s_length = 0.3

p_length  = 2.0

fig_height   = s_length + 1.0

fig_width    = p_length + 0.4

fig = figure( figsize=(fig_width, fig_height) )

rect = [(0.2/fig_width), (0.5/fig_height),

(p_length/fig_width), (s_length/fig_height)]

meter = H_Meter(fig, rect,

xlim=( -0.1, p_length+0.1 ),

ylim=( -0.4, s_length+0.1 ),

xticks=[],

yticks=[],

)

meter.set_axis_off()

show()
``````

“”"

from future import division

from matplotlib.figure import Figure

from matplotlib.axes import Axes

import math

import types

from math import pi

class Meter(Axes):

``````def __init__(self, vertical, raw_values, raw_limits, raw_zones, attribute_name, field_names, file_name, resolution, p_length, s_length, *args, **kwargs):

Axes.__init__(self, *args, **kwargs)

#Perform Checking

if( raw_limits[0] == raw_limits[1] ):

raise ValueError('identical_limits_exception: %s' % raw_limits)

if( raw_limits[1] > raw_limits[0] ):

self.graph_positive = True

else:   #Swap the limits around

self.graph_positive = False

raw_limits[0], raw_limits[1] = raw_limits[1] = raw_limits[0]

if not( ((raw_limits[2]/raw_limits[3]) % 1.0) * raw_limits[3] == 0 ):   #There must be an integer number of minor ticks for each major tick

if( raw_limits[2] <= 0 or raw_limits[3] <= 0 or raw_limits[2] < raw_limits[3] or raw_limits[3] > abs(raw_limits[1]-raw_limits[0]) ):

for zone in raw_zones:

if( zone[0] > zone[1] ):        #Swap the zones so zone[1] > zone[0]

zone[0], zone[1] = zone[1] = zone[0]

if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] ):

if( zone[0] < raw_limits[0] ):

zone[0] = raw_limits[0]

if( zone[1] > raw_limits[1] ):

zone[1] = raw_limits[1]

self.scaled_limits = []

for limit in raw_limits:

self.scaled_limits.append( limit * p_length / (raw_limits[1]-raw_limits[0]))

#Stuff all of the variables into self.

self.vertical = vertical

self.raw_values = raw_values

self.raw_limits = raw_limits

self.raw_zones = raw_zones

self.attribute_name = attribute_name

self.field_names = field_names

self.file_name = file_name

self.resolution = resolution

self.p_length = p_length

self.s_length = s_length

#Draw the meter

self.graph_center = ((self.scaled_limits[1]+self.scaled_limits[0])/2)

for zone in raw_zones:

self.draw_bar( zone, False)

self.draw_bar( None, True)

self.draw_dividers()

self.draw_ticks()

self.draw_needle()

if( vertical ):

self.text( self.s_length/2, self.scaled_limits[1]+0.05, self.attribute_name, size=12, va='bottom', ha='center')

else:

self.text( self.graph_center, self.s_length+0.05, self.attribute_name, size=12, va='bottom', ha='center')

def draw_bar( self, zone, border):

if( border ):

start  = self.scaled_limits[0]

end    = self.scaled_limits[1]

else:

start  = (zone[0] * self.p_length / (self.raw_limits[1]-self.raw_limits[0]))

end    = (zone[1] * self.p_length / (self.raw_limits[1]-self.raw_limits[0]))

colour =  zone[2]

if( not self.graph_positive ):

start  = -start

end    = -end

s_vect = [ 0.0, 0.0, self.s_length, self.s_length ]

p_vect = [ start, end, end, start ]

if( border ):

#Close the loop

p_vect.append(start)

s_vect.append(0.0)

if( self.vertical ):

p = self.plot(s_vect, p_vect, 'b-', color='black', linewidth=1.5)

else:

p = self.plot(p_vect, s_vect, 'b-', color='black', linewidth=1.5)

else:

if( self.vertical ):

p = self.fill(s_vect, p_vect, colour, linewidth=0.0, alpha=0.4)

else:

p = self.fill(p_vect, s_vect, colour, linewidth=0.0, alpha=0.4)

def draw_dividers( self ):

i = 1

num_fields = len(self.raw_values)

while( i < num_fields ):

s_vect = [

(i * self.s_length)/num_fields,

(i * self.s_length)/num_fields,

]

p_vect = [

self.scaled_limits[0],

self.scaled_limits[1],

]

if( self.vertical ):

self.plot(s_vect, p_vect, 'b-', color='black', linewidth=1.0)

else:

self.plot(p_vect, s_vect, 'b-', color='black', linewidth=1.0)

i += 1

def draw_needle( self ):

i = 0

for raw_value in self.raw_values:

if( raw_value == None ):

if( self.vertical ):

self.text( ((i + 1) * self.s_length)/len(self.raw_values),(self.scaled_limits[0]-0.05), "%s : N/A" % self.field_names[i], size=10, va='top', ha='right', rotation=45)

else:

self.text( (self.scaled_limits[0] - 0.05), ((i + 0.5) * self.s_length)/len(self.raw_values), "%s : N/A" % self.field_names[i], size=10, va='center', ha='right')

else:

#Clamp the value to the limits

value = raw_value * self.p_length / (self.raw_limits[1]-self.raw_limits[0])

if( raw_value < self.raw_limits[0] ):

value = self.raw_limits[0] * self.p_length / (self.raw_limits[1]-self.raw_limits[0])

if( raw_value > self.raw_limits[1] ):

value = self.raw_limits[1] * self.p_length / (self.raw_limits[1]-self.raw_limits[0])

if( self.vertical ):

self.text( ((i + 1) * self.s_length)/len(self.raw_values),(self.scaled_limits[0] - 0.05), "%s : %.2f" % (self.field_names[i], raw_value), size=10, va='top', ha='right', rotation=45)

else:

self.text( (self.scaled_limits[0] - 0.05), ((i + 0.5) * self.s_length)/len(self.raw_values), "%s : %.2f" % (self.field_names[i], raw_value), size=10, va='center', ha='right')

if( not self.graph_positive ):

value = -value

s_vect = [

((i + 0  ) * self.s_length)/len(self.raw_values),

((i + 0.5) * self.s_length)/len(self.raw_values),

((i + 1  ) * self.s_length)/len(self.raw_values),

((i + 0.5) * self.s_length)/len(self.raw_values),

]

p_vect = [

value,

value - 0.05,

value,

value + 0.05,

]

if( self.vertical ):

self.fill(s_vect, p_vect, 'b', alpha=0.4)

else:

self.fill(p_vect, s_vect, 'b', alpha=0.4)

i += 1

def draw_ticks( self ):

num_fields = len(self.raw_values)

if( self.graph_positive ):

offset = self.scaled_limits[0]

else:

offset = self.scaled_limits[1]

i = 0

j = self.raw_limits[0]

while( i*self.scaled_limits[3] + self.scaled_limits[0] <= self.scaled_limits[1] ):

if( i % (self.scaled_limits[2]/self.scaled_limits[3]) == 0):

tick_length = self.s_length

if( self.vertical ):

if( type(self.raw_limits[2]) is types.FloatType ):

self.text( -0.05, offset, "%.2f" % j, size=10, va='center', ha='right')

else:

self.text( -0.05, offset, "%d" % int(j), size=10, va='center', ha='right')

else:

if( type(self.raw_limits[2]) is types.FloatType ):

self.text( offset, -0.05, "%.2f" % j, size=10, va='top', ha='center')

else:

self.text( offset, -0.05, "%d" % int(j), size=10, va='top', ha='center')

j += self.raw_limits[2]

else:

tick_length = (self.s_length/num_fields) * 0.2

s_vect = [ 0.0, tick_length ]

p_vect = [ offset, offset ]

if( self.vertical ):

p = self.plot(s_vect, p_vect, 'b-', linewidth=1, color='black', alpha=0.2)

else:

p = self.plot(p_vect, s_vect, 'b-', linewidth=1, color='black', alpha=0.2)

i += 1

if( self.graph_positive ):

offset += self.scaled_limits[3]

else:

offset -= self.scaled_limits[3]

if( i % (self.scaled_limits[2]/self.scaled_limits[3]) == 0):

if( self.vertical ):

if( type(self.raw_limits[2]) is types.FloatType ):

self.text( -0.01, offset, "%.2f" % j, size=10, va='top', ha='center')

else:

self.text( -0.01, offset, "%d" % int(j), size=10, va='top', ha='center')

else:

if( type(self.raw_limits[2]) is types.FloatType ):

self.text( offset, -0.1, "%.2f" % j, size=10, va='top', ha='center')

else:

self.text( offset, -0.1, "%d" % int(j), size=10, va='top', ha='center')
``````

def make_widget( vertical, raw_values, raw_limits, raw_zones, attribute_name, field_names, file_name, resolution=72 ):

``````from pylab import figure, show, savefig

p_length = 4.0  # Length of the Primary axis

s_length = 0.3 * len(raw_values)  # Length of the Secondary axis

if( vertical ):

fig_height = p_length + 1.6

fig_width  = s_length + 1.1

fig = figure( figsize=(fig_width, fig_height) )

rect = [(0.9/fig_width), (1.3/fig_height), (s_length/fig_width), (p_length/fig_height)]

meter = Meter(vertical, raw_values,

raw_limits, raw_zones,

attribute_name, field_names,

file_name, resolution,

p_length, s_length,

fig, rect,

xlim=( -0.2, s_length+0.1 ),

ylim=( -0.1, p_length+0.1 ),

xticks=[],

yticks=[]

)

else:

fig_height = s_length + 0.5

fig_width  = p_length + 1.9

fig = figure( figsize=(fig_width, fig_height) )

rect = [(1.7/fig_width), (0.2/fig_height), (p_length/fig_width), (s_length/fig_height)]

meter = Meter(vertical, raw_values,

raw_limits, raw_zones,

attribute_name, field_names,

file_name, resolution,

p_length, s_length,

fig, rect,

xlim=( -0.1, p_length+0.1 ),

ylim=( -0.4, s_length+0.1 ),

xticks=[],

yticks=[],

)

meter.set_axis_off()

``````

# show()

``````fig.canvas.print_figure( file_name,dpi=resolution )
``````

#make_widget( False, [-3.0, 6.0, None, 0.25], [-10.0,10.0,5,1], [[-10.0,0.0,‘r’],[0.0,5.0,‘y’],[5.0,10.0,‘g’]], “Rx MOS (24h)”, [‘WLL to LAS’,‘LAS to WLL’,‘WLL to LAS’,‘LAS to WLL’], ‘multimeter.png’, 100)

‘’’

if name==‘main’:

``````from pylab import figure, show, savefig

vertical = False

raw_values = [-3.0, 6.0, None, 0.25]

raw_limits = [-10.0,10.0,5,1]

raw_zones = [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]

attribute_name = "Rx MOS (24h)"

field_names = ['WLL to LAS','LAS to WLL','WLL to LAS','LAS to WLL']

p_length = 4.0  # Length of the Primary axis

s_length = 0.3 * len(raw_values)  # Length of the Secondary axis

if( vertical ):

fig_height = p_length + 1.6

fig_width  = s_length + 1.1

fig = figure( figsize=(fig_width, fig_height) )

rect = [(0.9/fig_width), (1.3/fig_height), (s_length/fig_width), (p_length/fig_height)]

meter = Meter(fig, rect,

xlim=( -0.2, s_length+0.1 ),

ylim=( -0.1, p_length+0.1 ),

xticks=[],

yticks=[],

)

else:

fig_height = s_length + 0.5

fig_width  = p_length + 1.9

fig = figure( figsize=(fig_width, fig_height) )

rect = [(1.7/fig_width), (0.2/fig_height), (p_length/fig_width), (s_length/fig_height)]

meter = Meter(fig, rect,

xlim=( -0.1, p_length+0.1 ),

ylim=( -0.4, s_length+0.1 ),

xticks=[],

yticks=[],

)

meter.set_axis_off()

``````fig.canvas.print_figure('multimeter',dpi=72)