Gauges again, source code this time.
Apparently the mailing list doesn’t do attachments. So here is the source instead:
- Jamil Khan
Design Engineer,
Calyptech Pty. Ltd.
···
===========================================================================
linear rotary gauge
===========================================================================
#!/usr/bin/env python
This program draws a semi-circular gauge. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ lower, upper, major ticks, minor ticks],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “gauge_0.png”,
resolution in dpi
)
from pylab import *
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
import math
import types
import matplotlib
matplotlib.use(‘Agg’) # force the antigrain backend
from matplotlib.backends.backend_agg import FigureCanvasAgg
def draw_arch(limits, start_angle, end_angle, colour, border, graph_positive):
x_vect = []
y_vect = []
if( graph_positive ):
start = int(180 - (start_angle - limits[0]) * (180.0/(limits[1]-limits[0])))
end = int(180 - (end_angle - limits[0]) * (180.0/(limits[1]-limits[0])))
else:
start = int( (end_angle - limits[0]) * (180.0/(limits[1]-limits[0])))
end = int( (start_angle - limits[0]) * (180.0/(limits[1]-limits[0])))
#Draw the arch
theta = start
radius = 0.85
while (theta >= end):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta -= 1
theta = end
radius = 1.0
while (theta <= start):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta += 1
if( border ):
#Close the loop
x_vect.append(-0.85)
y_vect.append(0.0)
p = plot(x_vect, y_vect, 'b-')
setp(p, color='black')
setp(p, linewidth=1.5)
else:
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle(current_value, limits, graph_positive):
x_vect = []
y_vect = []
if current_value == None:
text(0.0, 0.4, "N/A", size=10, va='bottom', ha='center')
else:
text(0.0, 0.4, "%.2f" % current_value, size=10, va='bottom', ha='center')
#Clamp the value to the limits
if( current_value < limits[0] ):
current_value = limits[0]
if( current_value > limits[1] ):
current_value = limits[1]
theta = 0
length = 0.95
if( graph_positive ):
angle = 180.0 - (current_value - limits[0]) *(180.0/abs(limits[1]-limits[0]))
else:
angle = (current_value - limits[0]) *(180.0/abs(limits[1]-limits[0]))
while (theta <= 270):
x_vect.append( length * math.cos((theta + angle) * (pi/180)) )
y_vect.append( length * math.sin((theta + angle) * (pi/180)) )
length = 0.05
theta += 90
p = fill(x_vect, y_vect, 'b')
setp(p, alpha=0.4)
def draw_ticks(limits, graph_positive):
if( graph_positive ):
angle = 180.0
else:
angle = 0.0
i = 0
j = limits[0]
iterating = True
while( i*limits[3] + limits[0] <= limits[1] ):
x_vect = []
y_vect = []
if( i % (limits[2]/limits[3]) == 0 ):
x_pos = 1.1 * math.cos( angle * (pi/180.0))
y_pos = 1.1 * math.sin( angle * (pi/180.0))
if( type(limits[2]) is types.FloatType ):
text( x_pos, y_pos, "%.2f" % j, size=10, va='center', ha='center', rotation=(angle - 90))
else:
text( x_pos, y_pos, "%d" % int(j), size=10, va='center', ha='center', rotation=(angle - 90))
tick_length = 0.15
j += limits[2]
else:
tick_length = 0.05
i += 1
x_vect.append( 1.0 * math.cos( angle * (pi/180.0)))
x_vect.append( (1.0 - tick_length) * math.cos( angle * (pi/180.0)))
y_vect.append( 1.0 * math.sin( angle * (pi/180.0)))
y_vect.append( (1.0 - tick_length) * math.sin( angle * (pi/180.0)))
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, alpha=0.4)
setp(p, color="black")
if( graph_positive ):
angle -= limits[3] * (180.0/abs(limits[1]-limits[0]))
else:
angle += limits[3] * (180.0/abs(limits[1]-limits[0]))
if( i % (limits[2]/limits[3]) == 0 ):
x_pos = 1.1 * math.cos( angle * (pi/180.0))
y_pos = 1.1 * math.sin( angle * (pi/180.0))
if( type(limits[2]) is types.FloatType ):
text( x_pos, y_pos, "%.2f" % j, size=10, va='center', ha='center', rotation=(angle - 90))
else:
text( x_pos, y_pos, "%d" % int(j), size=10, va='center', ha='center', rotation=(angle - 90))
def draw_bounding_box(graph_width, graph_height):
x_vect = []
y_vect = []
x_vect.append( (graph_width/2) )
x_vect.append( (graph_width/2) )
x_vect.append(-(graph_width/2) )
x_vect.append(-(graph_width/2) )
x_vect.append( (graph_width/2) )
y_vect.append(-0.1)
y_vect.append(graph_height)
y_vect.append(graph_height)
y_vect.append(-0.1)
y_vect.append(-0.1)
p = plot(x_vect, y_vect, 'r-')
setp(p, linewidth=0)
def draw_widget( current_value, limits, zone_colour, attribute_name, filename, resolution=72 ):
graph_height = 1.6
graph_width = 2.4
fig_height = graph_height
fig_width = graph_width
figure(figsize=(fig_width, fig_height ))
a = axes([(0.0/fig_width), (0.2/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( -0.1, graph_width+0.1 ), ylim=( -0.4, graph_height+0.1 ), xticks=[], yticks=[])
axis('off')
#Perform Checking
if( limits[0] == limits[1] ):
raise 'identical_limits_exception', limits
if( limits[1] > limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = limits[0]
limits[0] = limits[1]
limits[1] = temp
if not( ((limits[2]/limits[3]) % 1.0) * limits[3] == 0 ): #There must be an integer number of minor ticks for each major tick
raise 'bad_tick_spacing_exception'
if( limits[2] <= 0 or limits[3] <= 0 or limits[2] < limits[3] or limits[3] > abs(limits[1]-limits[0]) ):
raise 'bad_limits_exception', limits
for zone in zone_colour:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < limits[0] or zone[0] > limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < limits[0] ):
zone[0] = limits[0]
if( zone[1] > limits[1] ):
zone[1] = limits[1]
#Draw the arch
for zone in zone_colour:
draw_arch(limits, zone[0], zone[1], zone[2], False, graph_positive)
draw_arch(limits, limits[0], limits[1], 'black', True, graph_positive)
draw_ticks(limits, graph_positive)
draw_needle(current_value, limits, graph_positive)
draw_bounding_box(graph_width, graph_height)
text(0.0, 0.2, attribute_name, size=10, va='bottom', ha='center')
#The black dot.
p = plot([0.0],[0.0],'.')
setp(p, color='#000000')
savefig( filename, dpi=resolution)
#draw_widget( 21.0, [4.0,20.0,4,1.0], [[4.0,10.0,‘r’],[10.0,14.0,‘y’],[14.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( -10.0, [-20.0,-4,4.0,1.0], [[-4.0,-10.0,‘r’],[-10.0,-14.0,‘y’],[-14.0,-20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( -10.5, [20.0,-20.0,4.0,1.0], [[-20.0,-15.0,‘r’],[-10.0,-15.0,‘y’],[-10.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( None, [4.0,20.0,4,1.0], [[4.0,10.0,‘r’],[10.0,14.0,‘y’],[14.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( 1.2, [4.0,10.0,2,0.5], [[4.0,6.0,‘r’],[6.0,8.0,‘y’],[8.0,10.0,‘g’]], “Rx MOS (24h)”, “gauge_1.png”, 100)
draw_widget( -4.0, [-1.0,1.0,1,0.1], [[-1.0,0.0,‘r’],[0.0,0.5,‘y’],[0.5,1.0,‘g’]], “Rx MOS (24h)”, “gauge_2.png”, 100)
#show()
===========================================================================
linear horizontal gauge
===========================================================================
#!/usr/bin/env python
This program draws a horizontal linear meter. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ lower, upper, major ticks, minor ticks],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “v_meter_0.png”,
resolution in dpi
)
from pylab import *
import types
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
#import math
def draw_bar( graph_positive, graph_height, start, end, colour):
x_vect = []
y_vect = []
y_vect.append( 0.0 )
y_vect.append( 0.0 )
y_vect.append( graph_height )
y_vect.append( graph_height )
if( graph_positive ):
x_vect.append( start )
x_vect.append( end )
x_vect.append( end )
x_vect.append( start )
else:
x_vect.append( -start )
x_vect.append( -end )
x_vect.append( -end )
x_vect.append( -start )
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle( graph_positive, true_value, true_limits, graph_height, graph_width, graph_center):
x_vect = []
y_vect = []
if( true_value == None ):
text( graph_center, (graph_height + 0.05), "N/A", size=10, va='bottom', ha='center')
else:
#Clamp the value to the limits
value = true_value * graph_width / (true_limits[1]-true_limits[0])
if( true_value < true_limits[0] ):
value = true_limits[0] * graph_width / (true_limits[1]-true_limits[0])
if( true_value > true_limits[1] ):
value = true_limits[1] * graph_width / (true_limits[1]-true_limits[0])
text( value, (graph_height + 0.05), "%.2f" % true_value, size=10, va='bottom', ha='center')
if( not graph_positive ):
value = -value
y_vect.append( graph_height/2 )
y_vect.append( graph_height )
y_vect.append( graph_height )
x_vect.append( value + 0.00 )
x_vect.append( value - 0.1 )
x_vect.append( value + 0.1 )
fill(x_vect, y_vect, 'black')
def draw_ticks( graph_positive, scaled_limits, true_limits, graph_height):
if( graph_positive ):
offset = scaled_limits[0]
else:
offset = scaled_limits[1]
i = 0
j = true_limits[0]
while( i*scaled_limits[3] + scaled_limits[0] <= scaled_limits[1] ):
x_vect = []
y_vect = []
if( i % (scaled_limits[2]/scaled_limits[3]) == 0):
tick_length = graph_height
if( type(true_limits[2]) is types.FloatType ):
text( offset, -0.05, "%.2f" % j, size=10, va='top', ha='center')
else:
text( offset, -0.05, "%d" % int(j), size=10, va='top', ha='center')
j += true_limits[2]
else:
tick_length = graph_height * 0.2
y_vect.append( 0.0 )
y_vect.append( tick_length )
x_vect.append( offset )
x_vect.append( offset )
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, color='black')
setp(p, alpha=0.2)
i += 1
if( graph_positive ):
offset += scaled_limits[3]
else:
offset -= scaled_limits[3]
if( i % (scaled_limits[2]/scaled_limits[3]) == 0):
if( type(true_limits[2]) is types.FloatType ):
text( offset, -0.05, "%.2f" % j, size=10, va='top', ha='center')
else:
text( offset, -0.05, "%d" % int(j), size=10, va='top', ha='center')
def draw_widget( true_value, true_limits, true_zones, attribute_name, filename, resolution=72 ):
graph_height = 0.3
graph_width = 2.0
fig_height = graph_height + 1.0
fig_width = graph_width + 0.4
#Perform Checking
if( true_limits[0] == true_limits[1] ):
raise 'identical_limits_exception', true_limits
if( true_limits[1] > true_limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = true_limits[0]
true_limits[0] = true_limits[1]
true_limits[1] = temp
if not( ((limits[2]/limits[3]) % 1.0) * limits[3] == 0 ): #There must be an integer number of minor ticks for each major tick
raise 'bad_tick_spacing_exception'
if( true_limits[2] <= 0 or true_limits[3] <= 0 or true_limits[2] < true_limits[3] or true_limits[3] > abs(true_limits[1]-true_limits[0]) ):
raise 'bad_limits_exception', true_limits
for zone in true_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < true_limits[0] or zone[0] > true_limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < true_limits[0] ):
zone[0] = true_limits[0]
if( zone[1] > true_limits[1] ):
zone[1] = true_limits[1]
#Adjust the scaling
scaled_limits = []
for limit in true_limits:
scaled_limits.append( limit * graph_width / (true_limits[1]-true_limits[0]))
figure(figsize=(fig_width, fig_height ))
a = axes([(0.2/fig_width), (0.5/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( 0, graph_width ), ylim=( 0, graph_height ), xticks=[], yticks=[])
#Draw the meter
graph_center = ((scaled_limits[1]+scaled_limits[0])/2)
for zone in true_zones:
draw_bar(graph_positive, graph_height, (zone[0] * graph_width / (true_limits[1]-true_limits[0])), (zone[1] * graph_width / (true_limits[1]-true_limits[0])), zone[2])
draw_ticks( graph_positive, scaled_limits, true_limits, graph_height )
draw_needle( graph_positive, true_value, true_limits, graph_height, graph_width, graph_center )
text( graph_center, graph_height+0.25, attribute_name, size=12, va='bottom', ha='center')
setp(gca(), xlim=( scaled_limits[0], scaled_limits[1] ))
savefig( filename, dpi=resolution)
#draw_widget( None, [4.0,20.0,4,0.1], [[4.0,10.0,‘r’],[10.0,14.0,‘y’],[14.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( 1.2, [4.0,10.0,2,0.5], [[4.0,6.0,‘r’],[6.0,8.0,‘y’],[8.0,10.0,‘g’]], “Rx MOS (24h)”, “gauge_1.png”, 100)
#draw_widget( -4.0, [-10.0,10.0,5.0,1.0], [[-10.0,0.0,‘r’],[0.0,5.0,‘y’],[5.0,10.0,‘g’]], “Rx MOS (24h)”, “gauge_2.png”, 100)
#draw_widget( -4.0, [-20.0,-4.0,4.0,1.0], [[-4.0,-10.0,‘r’],[-10.0,-14.0,‘y’],[-14.0,-20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( -11.36, [-40.0,-10.0,5.0,2.5], [[-40.0,-35.0,‘y’],[-35.0,-15.0,‘g’],[-15.0,10.0,‘y’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#show()
===========================================================================
linear vertical gauge
===========================================================================
#!/usr/bin/env python
This program draws a vertical linear meter. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ lower, upper, major ticks, minor ticks],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “v_meter_0.png”,
resolution in dpi
)
from pylab import *
import types
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
#import math
def draw_bar( graph_positive, graph_width, start, end, colour):
x_vect = []
y_vect = []
if not ( graph_positive ):
start = -start
end = -end
x_vect.append( 0.0 )
x_vect.append( 0.0 )
x_vect.append( graph_width )
x_vect.append( graph_width )
y_vect.append( start )
y_vect.append( end )
y_vect.append( end )
y_vect.append( start )
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle( graph_positive, true_value, true_limits, graph_width, graph_height, graph_center ):
x_vect = []
y_vect = []
if( true_value == None ):
text( (graph_width + 0.05), graph_center, "N/A", size=10, va='center', ha='left')
else:
#Clamp the value to the limits
value = true_value * graph_height / (true_limits[1]-true_limits[0])
if( true_value < true_limits[0] ):
value = true_limits[0] * graph_height / (true_limits[1]-true_limits[0])
if( true_value > true_limits[1] ):
value = true_limits[1] * graph_height / (true_limits[1]-true_limits[0])
text( (graph_width + 0.05), value, "%.2f" % true_value, size=10, va='center', ha='left')
if( not graph_positive ):
value = -value
x_vect.append( graph_width/2 )
x_vect.append( graph_width )
x_vect.append( graph_width )
y_vect.append( value + 0.00 )
y_vect.append( value - 0.1 )
y_vect.append( value + 0.1 )
fill(x_vect, y_vect, 'black')
def draw_ticks( graph_positive, scaled_limits, true_limits, graph_width):
if( graph_positive ):
offset = scaled_limits[0]
else:
offset = scaled_limits[1]
i = 0
j = true_limits[0]
while( i*scaled_limits[3] + scaled_limits[0] <= scaled_limits[1] ):
x_vect = []
y_vect = []
if( i % (scaled_limits[2]/scaled_limits[3]) == 0):
tick_length = graph_width
if( type(true_limits[2]) is types.FloatType ):
text(-0.05, offset, "%.2f" % j, size=10, va='center', ha='right')
else:
text(-0.05, offset, "%d" % int(j), size=10, va='center', ha='right')
j += true_limits[2]
else:
tick_length = graph_width * 0.2
x_vect.append( 0.0 )
x_vect.append( tick_length )
y_vect.append( offset )
y_vect.append( offset )
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, color='black')
setp(p, alpha=0.2)
i += 1
if( graph_positive ):
offset += scaled_limits[3]
else:
offset -= scaled_limits[3]
if( i % (scaled_limits[2]/scaled_limits[3]) == 0):
if( type(true_limits[2]) is types.FloatType ):
text(-0.05, offset, "%.2f" % j, size=10, va='center', ha='right')
else:
text(-0.05, offset, "%d" % int(j), size=10, va='center', ha='right')
def draw_widget( true_value, true_limits, true_zones, attribute_name, filename, resolution=72 ):
graph_height = 2.0
graph_width = 0.3
fig_height = graph_height + 0.4
fig_width = graph_width + 1.0
figure(figsize=(fig_width, fig_height ))
a = axes([(0.5/fig_width), (0.3/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( 0, graph_width ), ylim=( 0, graph_height ), xticks=[], yticks=[])
#Perform Checking
if( true_limits[0] == true_limits[1] ):
raise 'identical_limits_exception', true_limits
if( true_limits[1] > true_limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = true_limits[0]
true_limits[0] = true_limits[1]
true_limits[1] = temp
if not( ((limits[2]/limits[3]) % 1.0) * limits[3] == 0 ): #There must be an integer number of minor ticks for each major tick
raise 'bad_tick_spacing_exception'
if( true_limits[2] <= 0 or true_limits[3] <= 0 or true_limits[2] < true_limits[3] or true_limits[3] > abs(true_limits[1]-true_limits[0]) ):
raise 'bad_limits_exception', true_limits
for zone in true_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < true_limits[0] or zone[0] > true_limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < true_limits[0] ):
zone[0] = true_limits[0]
if( zone[1] > true_limits[1] ):
zone[1] = true_limits[1]
#Adjust the scaling
scaled_limits = []
for limit in true_limits:
scaled_limits.append( limit * graph_height / (true_limits[1]-true_limits[0]))
#Draw the meter
graph_center = ((true_limits[1]+true_limits[0])/2* graph_height / (true_limits[1]-true_limits[0]))
for zone in true_zones:
draw_bar(graph_positive, graph_width, (zone[0] * graph_height / (true_limits[1]-true_limits[0])), (zone[1] * graph_height / (true_limits[1]-true_limits[0])), zone[2])
draw_ticks( graph_positive, scaled_limits, true_limits, graph_width)
draw_needle( graph_positive, true_value, true_limits, graph_width, graph_height, graph_center )
text((graph_width/2), (scaled_limits[0]-0.1), attribute_name, size=12, va='top', ha='center')
setp(gca(), ylim=( scaled_limits[0], scaled_limits[1] ))
savefig( filename, dpi=resolution)
#draw_widget( None, [4.0,20.0,4,1.0], [[4.0,10.0,‘r’],[10.0,14.0,‘y’],[14.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( -10.0, [-20.0,-4.0,4.0,1.0], [[-4.0,-10.0,‘r’],[-10.0,-14.0,‘y’],[-14.0,-20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#draw_widget( -4.5, [20.0,-20.0,4.0,1.0], [[12.5-20.0,-15.0,‘r’],[-10.0,-15.0,‘y’],[-10.0,20.0,‘g’]], “Rx MOS (24h)”, “gauge_0.png”, 100)
#show()
===========================================================================
logarithmic rotary gauge
===========================================================================
#!/usr/bin/env python
This program draws a log semi-circular gauge. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ left, right],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “gauge_0.png”,
resolution in dpi
)
NOTE: The limits you specify must be of this form
for any value of ‘n’: 1.0*10^n
from pylab import *
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
import math
import matplotlib
matplotlib.use(‘Agg’) # force the antigrain backend
from matplotlib.backends.backend_agg import FigureCanvasAgg
def draw_arch(limits, start, end, colour, border, graph_positive):
x_vect = []
y_vect = []
if( graph_positive ):
start_value = int(180 - (start - limits[0]) * (180.0/(limits[1]-limits[0])))
end_value = int(180 - (end - limits[0]) * (180.0/(limits[1]-limits[0])))
else:
start_value = int( (end - limits[0]) * (180.0/(limits[1]-limits[0])))
end_value = int( (start - limits[0]) * (180.0/(limits[1]-limits[0])))
if( graph_positive ):
start_value = (math.log10(start) - math.log10(limits[1])) * 180.00 / -(math.log10(limits[1]) - math.log10(limits[0]))
end_value = (math.log10(end) - math.log10(limits[1])) * 180.00 / -(math.log10(limits[1]) - math.log10(limits[0]))
else:
start_value = (math.log10(end) - math.log10(limits[0])) * 180.00 / +(math.log10(limits[1]) - math.log10(limits[0]))
end_value = (math.log10(start) - math.log10(limits[0])) * 180.00 / +(math.log10(limits[1]) - math.log10(limits[0]))
#Draw the arch
theta = start_value
radius = 0.85
while (theta >= end_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta -= 1
theta = end_value
radius = 1.0
while (theta <= start_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta += 1
if( border ):
#Close the loop
x_vect.append(-0.85)
y_vect.append(0.0)
p = plot(x_vect, y_vect, 'b-')
setp(p, color='black')
setp(p, linewidth=1.5)
else:
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle(current_value, limits, graph_positive):
x_vect = []
y_vect = []
if current_value == None:
text(0.0, 0.0, "N/A", size=10, va='center', ha='center')
else:
text(0.0, 0.0, "%.2f" % current_value, size=10, va='center', ha='center')
#Clamp the value to the limits
if( current_value < limits[0] ):
current_value = limits[0]
if( current_value > limits[1] ):
current_value = limits[1]
theta = 0
length = 0.95
#if( graph_positive ):
# angle = 180 - (current_value - limits[0]) *(180.0/(limits[1]-limits[0]))
#else:
# angle = (current_value - limits[0]) *(180.0/(limits[1]-limits[0]))
if( graph_positive ):
angle = (math.log10(current_value) - math.log10(limits[1])) * 180.00 / -(math.log10(limits[1]) - math.log10(limits[0]))
else:
angle = (math.log10(current_value) - math.log10(limits[0])) * 180.00 / +(math.log10(limits[1]) - math.log10(limits[0]))
#angle = 180.0-180.0*(current_value/(limits[1] - limits[0]))
#while (theta <= 270):
x_vect.append( length * math.cos((theta + angle) * (pi/180)) )
y_vect.append( length * math.sin((theta + angle) * (pi/180)) )
x_vect.append( 0.2 * length * math.cos((theta + angle + 10.0) * (pi/180)) )
y_vect.append( 0.2 * length * math.sin((theta + angle + 10.0) * (pi/180)) )
x_vect.append( 0.15 * length * math.cos((theta + angle ) * (pi/180)) )
y_vect.append( 0.15 * length * math.sin((theta + angle ) * (pi/180)) )
x_vect.append( 0.2 * length * math.cos((theta + angle - 10.0) * (pi/180)) )
y_vect.append( 0.2 * length * math.sin((theta + angle - 10.0) * (pi/180)) )
# length = 0.05
# theta += 90
p = fill(x_vect, y_vect, 'b')
setp(p, alpha=0.4)
def draw_ticks(limits, graph_positive):
if( graph_positive ):
angle = 180.0
else:
angle = 0.0
i = limits[0]
step = limits[0]
x_vect = []
y_vect = []
while( i < limits[1] ):
while( i < (step * 10) ):
x_vect = []
y_vect = []
value = math.log10(i)
if( graph_positive ):
angle = (value - math.log10(limits[1])) * 180.00 / -(math.log10(limits[1]) - math.log10(limits[0]))
else:
angle = (value - math.log10(limits[0])) * 180.00 / +(math.log10(limits[1]) - math.log10(limits[0]))
x_pos = 1.1 * math.cos( angle * (pi/180.0))
y_pos = 1.1 * math.sin( angle * (pi/180.0))
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 or mantissa == 1 ):
print i, mantissa
text( x_pos, y_pos, "%g" % i, size=10, va='center', ha='center', rotation=(angle - 90))
tick_length = 0.15
else:
tick_length = 0.05
x_vect.append( 1.0 * math.cos( angle * (pi/180.0)))
x_vect.append( (1.0 - tick_length) * math.cos( angle * (pi/180.0)))
y_vect.append( 1.0 * math.sin( angle * (pi/180.0)))
y_vect.append( (1.0 - tick_length) * math.sin( angle * (pi/180.0)))
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, alpha=0.4)
setp(p, color="black")
i += step
i = step * 10
step = step * 10
i = limits[1]
value = math.log10(i)
if( graph_positive ):
angle = (value - math.log10(limits[1])) * 180.00 / -(math.log10(limits[1]) - math.log10(limits[0]))
else:
angle = (value - math.log10(limits[0])) * 180.00 / +(math.log10(limits[1]) - math.log10(limits[0]))
x_pos = 1.1 * math.cos( angle * (pi/180.0))
y_pos = 1.1 * math.sin( angle * (pi/180.0))
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 ):
text( x_pos, y_pos, "%g" % i, size=10, va='center', ha='center', rotation=(angle - 90))
def draw_bounding_box(graph_width, graph_height):
x_vect = []
y_vect = []
x_vect.append( (graph_width/2) )
x_vect.append( (graph_width/2) )
x_vect.append(-(graph_width/2) )
x_vect.append(-(graph_width/2) )
x_vect.append( (graph_width/2) )
y_vect.append(-0.1)
y_vect.append(graph_height)
y_vect.append(graph_height)
y_vect.append(-0.1)
y_vect.append(-0.1)
p = plot(x_vect, y_vect, 'r-')
setp(p, linewidth=0)
def draw_widget( current_value, limits, zone_colour, attribute_name, filename, resolution=72 ):
graph_height = 1.4
graph_width = 2.4
fig_height = graph_height
fig_width = graph_width
figure(figsize=(fig_width, fig_height ))
a = axes([(0.0/fig_width), (0.0/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( -0.1, graph_width+0.1 ), ylim=( -0.2, graph_height+0.1 ), xticks=[], yticks=[])
axis('off')
#Perform Checking
if( limits[0] == limits[1] ):
raise 'identical_limits_exception', limits
if( limits[1] > limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = limits[0]
limits[0] = limits[1]
limits[1] = temp
if not( math.log10(limits[0]) % 1.0 == 0 and math.log10(limits[1]) % 1.0 == 0 ):
raise 'bad_limits_exception'
for zone in zone_colour:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < limits[0] or zone[0] > limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < limits[0] ):
zone[0] = limits[0]
if( zone[1] > limits[1] ):
zone[1] = limits[1]
#Draw the arch
for zone in zone_colour:
draw_arch(limits, zone[0], zone[1], zone[2], False, graph_positive)
draw_arch(limits, limits[0], limits[1], 'black', True, graph_positive)
draw_ticks(limits, graph_positive)
draw_needle(current_value, limits, graph_positive)
draw_bounding_box(graph_width, graph_height)
text(0.0, 0.3, attribute_name, size=10, va='center', ha='center')
savefig( filename, dpi=resolution)
#draw_widget( 0.02, [0.0001,1.0], [[0.0001,0.01,‘g’], [0.01,0.05,‘y’],[0.05,1.0,‘r’]], “Sat. Clipping”, “log_0.png”, 100)
#draw_widget( 0.02, [10.0,0.001], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,10.0,‘r’]], “Sat. Clipping”, “log_0.png”, 100)
#draw_widget( 0.02, [10.0,0.001], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,8.0,‘r’]], “Sat. Clipping”, “log_0.png”, 100)
#draw_widget( 20.0, [1000.0,1.0], [[1.0,10.0,‘g’], [10.0,100.0,‘y’],[100.0,1000.0,‘r’]], “Sat. Clipping”, “log_0.png”, 100)
#show()
===========================================================================
logarithmic horizontal gauge
===========================================================================
#!/usr/bin/env python
This program draws a log horizontal gauge. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ left, right],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “gauge_0.png”,
resolution in dpi
)
NOTE: The limits you specify must be of this form
for any value of ‘n’: 1.0*10^n
from pylab import *
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
import math
import matplotlib
matplotlib.use(‘Agg’) # force the antigrain backend
from matplotlib.backends.backend_agg import FigureCanvasAgg
def draw_arch(limits, start, end, colour, graph_width, graph_positive):
x_vect = []
y_vect = []
if( graph_positive ):
start_value = math.log10(start)
end_value = math.log10(end)
else:
start_value = - math.log10(start)
end_value = - math.log10(end)
y_vect.append( 0.0 )
y_vect.append( 0.0 )
y_vect.append( graph_width )
y_vect.append( graph_width )
x_vect.append( start_value )
x_vect.append( end_value )
x_vect.append( end_value )
x_vect.append( start_value )
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle(current_value, limits, graph_positive, graph_width, graph_center):
x_vect = []
y_vect = []
if current_value == None:
text( (graph_width + 0.1), graph_center, "N/A", size=10, va='center', ha='left')
else:
#Clamp the value to the limits
if( current_value < limits[0] ):
current_value = limits[0]
if( current_value > limits[1] ):
current_value = limits[1]
if( graph_positive ):
offset = math.log10(current_value)
else:
offset = -math.log10(current_value)
text( offset, (graph_width + 0.1), "%g" % current_value, size=10, va='center', ha='left')
y_vect.append( graph_width/2 )
y_vect.append( graph_width )
y_vect.append( graph_width )
x_vect.append( offset + 0.00 )
x_vect.append( offset - 0.1 )
x_vect.append( offset + 0.1 )
fill(x_vect, y_vect, 'black')
def draw_ticks(limits, graph_positive, graph_width):
i = limits[0]
step = limits[0]
x_vect = []
y_vect = []
while( i < limits[1] ):
while( i < (step * 10) ):
x_vect = []
y_vect = []
value = math.log10(i)
if( graph_positive ):
offset = value
else:
offset =-value
x_pos = 1.1 * math.cos( offset * (pi/180.0))
y_pos = 1.1 * math.sin( offset * (pi/180.0))
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 or mantissa == 1 ):
text( offset, -0.05, "%g" % i, size=10, va='top', ha='center')
tick_length = graph_width
else:
tick_length = graph_width * 0.2
y_vect.append( 0.0 )
y_vect.append( tick_length )
x_vect.append( offset )
x_vect.append( offset )
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, color='black')
setp(p, alpha=0.2)
i += step
i = step * 10
step = step * 10
i = limits[1]
value = math.log10(i)
if( graph_positive ):
offset = value
else:
offset =-value
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 ):
text( offset, -0.05, "%g" % i, size=10, va='top', ha='center')
def draw_widget( current_value, limits, zone_colour, attribute_name, filename, resolution=72 ):
graph_height = 0.3
graph_width = 2.0
fig_height = graph_height + 1.0
fig_width = graph_width + 0.4
figure(figsize=(fig_width, fig_height ))
a = axes([(0.2/fig_width), (0.5/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( 0.0, graph_width ), ylim=( 0.0, graph_height ), xticks=[], yticks=[])
#Perform Checking
if( limits[0] == limits[1] ):
raise 'identical_limits_exception', limits
if( limits[1] > limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = limits[0]
limits[0] = limits[1]
limits[1] = temp
if not( math.log10(limits[0]) % 1.0 == 0 and math.log10(limits[1]) % 1.0 == 0 ):
raise 'bad_limits_exception'
for zone in zone_colour:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < limits[0] or zone[0] > limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < limits[0] ):
zone[0] = limits[0]
if( zone[1] > limits[1] ):
zone[1] = limits[1]
#Draw the arch
graph_center = ((math.log10(limits[1])+math.log10(limits[0]))/2.0)
for zone in zone_colour:
draw_arch(limits, zone[0], zone[1], zone[2], graph_height, graph_positive)
draw_ticks(limits, graph_positive, graph_height)
draw_needle(current_value, limits, graph_positive, graph_height, graph_center)
if( graph_positive ):
setp(gca(), xlim=( math.log10(limits[0]), math.log10(limits[1]) ))
text( graph_center, -0.3, attribute_name, size=12, va='top', ha='center')
else:
setp(gca(), xlim=( -math.log10(limits[1]), -math.log10(limits[0]) ))
text( -graph_center, -0.3, attribute_name, size=12, va='top', ha='center')
savefig( filename, dpi=resolution)
#draw_widget( 0.02, [0.0001,1.0], [[0.0001,0.01,‘g’], [0.01,0.05,‘y’],[0.05,1.0,‘r’]], “Normal”, “log_0.png”, 100)
#draw_widget( 0.02, [1.0,0.0001], [[0.0001,0.01,‘g’], [0.01,0.05,‘y’],[0.05,1.0,‘r’]], “Backwards”, “log_0.png”, 100)
#draw_widget( 0.02, [0.001,10.0], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,10.0,‘r’]], “None”, “log_0.png”, 100)
#draw_widget( 0.20, [10.0,0.001], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,10.0,‘r’]], “Shmoo”, “log_0.png”, 100)
#draw_widget( 20.0, [1000.0,1.0], [[1.0,10.0,‘g’], [10.0,100.0,‘y’],[100.0,1000.0,‘r’]], “> 1.0”, “log_0.png”, 100)
#show()
===========================================================================
logarithmic vertical gauge
===========================================================================
#!/usr/bin/env python
This program draws a log vertical gauge. You supply limits,
shaded regions, names and the current value, and invoke
it like this:
draw_widget( current_value,
limits[ left, right],
shaded zones [ [lower,upper,colour],
[lower,upper,colour],
…],
name “MOS”,
filename “gauge_0.png”,
resolution in dpi
)
NOTE: The limits you specify must be of this form
for any value of ‘n’: 1.0*10^n
from pylab import *
#from matplotlib.patches import Patch, Rectangle, Circle, Polygon, Wedge, Shadow, bbox_artist
import math
import matplotlib
matplotlib.use(‘Agg’) # force the antigrain backend
from matplotlib.backends.backend_agg import FigureCanvasAgg
def draw_arch(limits, start, end, colour, graph_width, graph_positive):
x_vect = []
y_vect = []
if( graph_positive ):
start_value = math.log10(start)
end_value = math.log10(end)
else:
start_value = - math.log10(start)
end_value = - math.log10(end)
x_vect.append( 0.0 )
x_vect.append( 0.0 )
x_vect.append( graph_width )
x_vect.append( graph_width )
y_vect.append( start_value )
y_vect.append( end_value )
y_vect.append( end_value )
y_vect.append( start_value )
p = fill(x_vect, y_vect, colour)
setp(p, linewidth=0.0)
setp(p, alpha=0.4)
def draw_needle(current_value, limits, graph_positive, graph_width, graph_center):
x_vect = []
y_vect = []
if current_value == None:
text( (graph_width + 0.05), graph_center, "N/A", size=10, va='center', ha='left')
else:
#Clamp the value to the limits
if( current_value < limits[0] ):
current_value = limits[0]
if( current_value > limits[1] ):
current_value = limits[1]
if( graph_positive ):
offset = math.log10(current_value)
else:
offset = -math.log10(current_value)
text( (graph_width + 0.05), offset, "%g" % current_value, size=10, va='center', ha='left')
x_vect.append( graph_width/2 )
x_vect.append( graph_width )
x_vect.append( graph_width )
y_vect.append( offset + 0.00 )
y_vect.append( offset - 0.1 )
y_vect.append( offset + 0.1 )
fill(x_vect, y_vect, 'black')
def draw_ticks(limits, graph_positive, graph_width):
i = limits[0]
step = limits[0]
x_vect = []
y_vect = []
while( i < limits[1] ):
while( i < (step * 10) ):
x_vect = []
y_vect = []
value = math.log10(i)
if( graph_positive ):
offset = value
else:
offset =-value
x_pos = 1.1 * math.cos( offset * (pi/180.0))
y_pos = 1.1 * math.sin( offset * (pi/180.0))
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 or mantissa == 1 ):
text(-0.05, offset, "%g" % i, size=10, va='center', ha='right')
tick_length = graph_width
else:
tick_length = graph_width * 0.2
x_vect.append( 0.0 )
x_vect.append( tick_length )
y_vect.append( offset )
y_vect.append( offset )
p = plot(x_vect, y_vect, 'b-')
setp(p, linewidth=1)
setp(p, color='black')
setp(p, alpha=0.2)
i += step
i = step * 10
step = step * 10
i = limits[1]
value = math.log10(i)
if( graph_positive ):
offset = value
else:
offset =-value
x_pos = 1.1 * math.cos( offset * (pi/180.0))
y_pos = 1.1 * math.sin( offset * (pi/180.0))
mantissa = int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa == 10 ):
text(-0.05, offset, "%g" % i, size=10, va='center', ha='right')
def draw_widget( current_value, limits, zone_colour, attribute_name, filename, resolution=72 ):
graph_height = 2.0
graph_width = 0.3
fig_height = graph_height + 0.4
fig_width = graph_width + 1.0
figure(figsize=(fig_width, fig_height ))
a = axes([(0.5/fig_width), (0.3/fig_height), (graph_width/fig_width), (graph_height/fig_height)])
setp(a, xlim=( 0.0, graph_width ), ylim=( 0.0, graph_height ), xticks=[], yticks=[])
#Perform Checking
if( limits[0] == limits[1] ):
raise 'identical_limits_exception', limits
if( limits[1] > limits[0] ):
graph_positive = True
else: #Swap the limits around
graph_positive = False
temp = limits[0]
limits[0] = limits[1]
limits[1] = temp
if not( math.log10(limits[0]) % 1.0 == 0 and math.log10(limits[1]) % 1.0 == 0 ):
raise 'bad_limits_exception'
for zone in zone_colour:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > zone[0]
temp = zone[0]
zone[0] = zone[1]
zone[1] = temp
if( zone[1] < limits[0] or zone[0] > limits[1] ):
raise 'bad_zone_exception', zone
if( zone[0] < limits[0] ):
zone[0] = limits[0]
if( zone[1] > limits[1] ):
zone[1] = limits[1]
#Draw the arch
graph_center = ((math.log10(limits[1])+math.log10(limits[0]))/2.0)
for zone in zone_colour:
draw_arch(limits, zone[0], zone[1], zone[2], graph_width, graph_positive)
draw_ticks(limits, graph_positive, graph_width)
draw_needle(current_value, limits, graph_positive, graph_width, graph_center)
if( graph_positive ):
setp(gca(), ylim=( math.log10(limits[0]), math.log10(limits[1]) ))
text((graph_width/2), (math.log10(limits[0])-0.1), attribute_name, size=12, va='top', ha='center')
else:
setp(gca(), ylim=( -math.log10(limits[1]), -math.log10(limits[0]) ))
text((graph_width/2), -(math.log10(limits[1])+0.1), attribute_name, size=12, va='top', ha='center')
savefig( filename, dpi=resolution)
#draw_widget( 0.02, [0.0001,1.0], [[0.0001,0.01,‘g’], [0.01,0.05,‘y’],[0.05,1.0,‘r’]], “Normal”, “log_0.png”, 100)
#draw_widget( 0.02, [1.0,0.0001], [[0.0001,0.01,‘g’], [0.01,0.05,‘y’],[0.05,1.0,‘r’]], “Backwards”, “log_0.png”, 100)
#draw_widget( 0.02, [0.001,10.0], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,10.0,‘r’]], “None”, “log_0.png”, 100)
#draw_widget( 0.20, [10.0,0.001], [[0.001,0.1,‘g’], [0.1,0.5,‘y’],[0.5,10.0,‘r’]], “Shmoo”, “log_0.png”, 100)
#draw_widget( 20.0, [1000.0,1.0], [[1.0,10.0,‘g’], [10.0,100.0,‘y’],[100.0,1000.0,‘r’]], “> 1.0”, “log_0.png”, 100)
#show()