You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(33) |
Dec
(20) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(7) |
Feb
(44) |
Mar
(51) |
Apr
(43) |
May
(43) |
Jun
(36) |
Jul
(61) |
Aug
(44) |
Sep
(25) |
Oct
(82) |
Nov
(97) |
Dec
(47) |
| 2005 |
Jan
(77) |
Feb
(143) |
Mar
(42) |
Apr
(31) |
May
(93) |
Jun
(93) |
Jul
(35) |
Aug
(78) |
Sep
(56) |
Oct
(44) |
Nov
(72) |
Dec
(75) |
| 2006 |
Jan
(116) |
Feb
(99) |
Mar
(181) |
Apr
(171) |
May
(112) |
Jun
(86) |
Jul
(91) |
Aug
(111) |
Sep
(77) |
Oct
(72) |
Nov
(57) |
Dec
(51) |
| 2007 |
Jan
(64) |
Feb
(116) |
Mar
(70) |
Apr
(74) |
May
(53) |
Jun
(40) |
Jul
(519) |
Aug
(151) |
Sep
(132) |
Oct
(74) |
Nov
(282) |
Dec
(190) |
| 2008 |
Jan
(141) |
Feb
(67) |
Mar
(69) |
Apr
(96) |
May
(227) |
Jun
(404) |
Jul
(399) |
Aug
(96) |
Sep
(120) |
Oct
(205) |
Nov
(126) |
Dec
(261) |
| 2009 |
Jan
(136) |
Feb
(136) |
Mar
(119) |
Apr
(124) |
May
(155) |
Jun
(98) |
Jul
(136) |
Aug
(292) |
Sep
(174) |
Oct
(126) |
Nov
(126) |
Dec
(79) |
| 2010 |
Jan
(109) |
Feb
(83) |
Mar
(139) |
Apr
(91) |
May
(79) |
Jun
(164) |
Jul
(184) |
Aug
(146) |
Sep
(163) |
Oct
(128) |
Nov
(70) |
Dec
(73) |
| 2011 |
Jan
(235) |
Feb
(165) |
Mar
(147) |
Apr
(86) |
May
(74) |
Jun
(118) |
Jul
(65) |
Aug
(75) |
Sep
(162) |
Oct
(94) |
Nov
(48) |
Dec
(44) |
| 2012 |
Jan
(49) |
Feb
(40) |
Mar
(88) |
Apr
(35) |
May
(52) |
Jun
(69) |
Jul
(90) |
Aug
(123) |
Sep
(112) |
Oct
(120) |
Nov
(105) |
Dec
(116) |
| 2013 |
Jan
(76) |
Feb
(26) |
Mar
(78) |
Apr
(43) |
May
(61) |
Jun
(53) |
Jul
(147) |
Aug
(85) |
Sep
(83) |
Oct
(122) |
Nov
(18) |
Dec
(27) |
| 2014 |
Jan
(58) |
Feb
(25) |
Mar
(49) |
Apr
(17) |
May
(29) |
Jun
(39) |
Jul
(53) |
Aug
(52) |
Sep
(35) |
Oct
(47) |
Nov
(110) |
Dec
(27) |
| 2015 |
Jan
(50) |
Feb
(93) |
Mar
(96) |
Apr
(30) |
May
(55) |
Jun
(83) |
Jul
(44) |
Aug
(8) |
Sep
(5) |
Oct
|
Nov
(1) |
Dec
(1) |
| 2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
(3) |
Nov
|
Dec
|
| 2017 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
(7) |
Oct
|
Nov
|
Dec
|
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: John H. <jdh...@ac...> - 2005-08-03 15:27:45
|
>>>>> "Steve" == Steve Chaplin <ste...@ya...> writes:
Steve> One problem with the colorbar is that the png file
Steve> "im.write_png (filename)" creates is upside down,
Steve> image_demo.py creates an upside down png too.
Steve> I see that the GTK/GDK backend does not use im.write_png()
Steve> but uses im.as_str() which has a 'flipud' argument to flip
Steve> the image. Is it possible for im.write_png() to take the
Steve> 'flipud' argument and flip the image for the SVG backend?
I started working on this, but then realized I would also need to add
it to buffer_argb32, buffer_rgba and so on, and that is was much
cleaner to simply add an im.flipud() method than implement it in all
the conversion and write methods.
I just committed changes with these fixes and updated backend_ps and
backend_svg to use them. images in svg appear to be working fine now,
and the origin = 'lower'|'upper' is respected.
Steve> The name im.as_str() is a bit vague - what kind of string?
Steve> Something like im.as_rgba_str() would make it a bit
Steve> clearer.
Done.
JDH
|
|
From: Stefan K. <pon...@ya...> - 2005-08-03 04:44:45
|
This is actually a bug in the Python installer for Solaris as described in this thread.. http://mail.python.org/pipermail/python-dev/2003-May/035560.html I changed the following 2 defines in pyconfig.h #define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE_EXTENDED 0 and it passed that compile error. ALSO, small bug in the matplotlib setupext.py, on line 531, the Numeric install does not include the numarray_inc_dirs value to the include list is is passing into the Extension object. S __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com |
|
From: Stefan K. <pon...@ya...> - 2005-08-02 23:40:00
|
I am trying to build matplotlib on Solaris and am getting the following
compile error. Does this look familiar to anyone?
thanks,
S
In file included from
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/bits/postypes.h:4\
6,
from
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/iosfwd:50,
from
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/ios:44,
from
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/ostream:45,
from
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/iostream:45,
from swig/agg_buffer.h:7,
from src/agg.cxx:1582:
/work/local-b/sparc-sun-solaris2.9/bin/../lib/gcc/sparc-sun-solaris2.9/3.4.2/../../../../include/c++/3.4.2/cwchar:145:
error: `::btowc' has not been declared
__________________________________
Yahoo! Mail for Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http://mobile.yahoo.com/learn/mail
|
|
From: John H. <jdh...@ac...> - 2005-08-02 22:45:54
|
I wrote once before (http://sourceforge.net/mailarchive/message.php?msg_id=12093643) about some new methods for animation that can enable fast animations in matplotlib, which can support everything from dynamically updating your data to strip charts to real time cursoring to a widget like canvas. So far, only GTKAgg has complete support for the required methods. I think it would be nice to have these in the major mpl GUI backends, since it would make the animation interface much simpler and cleaner if we could rely on them in the frontend, eg in the Axes class. I just posted an entry on the wiki about matplotlib animations. It starts with regular "pylab" animations, and then discusses GUI animations using timers and event handlers, and finally the newfangled methods to support per-artist animations. As it turns out, for the *Agg backends, only one new method needs to be added, which is canvas.blit(bbox) This method transfers the agg canvas within the bounding box onto the GUI canvas. I realize that I need to add something like aggcanvas.as_rgba_str(bbox) to support this for Qt and WX which are currently using string methods to blit to canvas. I'm happy to do this in the next couple of days if I know that someone is interested in actually implementing canvas.blit(bbox) for their respective backend. To see the utility of the new methods, run examples/widgets/cursor.py and examples/widgets/span_selector.py modified to set useblit=True, and compare the performance of anim.py with examples/animation_blit.py which animate the same data. All of the above should be run done with the GTKAgg backend. As noted on the wiki entry, with these methods in place, users who want to do per artist animation could write code like line, = ax.plot(something, animated=True) canvas.draw() def callback(*args): line.set_ydata(somedata) ax.draw_animated() This *doesn't* work now, because I am hesitant to put methods into Axes which would break most backends. The equivalent in animation_blit.py is considerably more complicated. Perhaps someone at STScI could sign up for implementing canvas.blit(bbox) for TkAgg, and someone at JPL for the Qt backend? I might take a crack at WX, if noone else wants it :-) Steve, Gregory and Charles, if you are interested in animation for your respective backends, I encourage you to take a look at this too. Those of you using the agg buffer in extension code (eg tkagg) may want to look at src/_gtkagg.cpp to see how the bbox and the agg buffer are used to implement blit, which defaults to blitting the entire canvas if blit=None. All of this is discussed in more depth at http://www.scipy.org/wikis/topical_software/Animations Thanks! JDH |
|
From: Steve C. <ste...@ya...> - 2005-08-02 14:54:22
|
On Mon, 2005-08-01 at 20:26 -0700,
mat...@li... wrote:
>
> In some cases, there appears to be a bug in SVG image
> handling. For
> example, the image in the colorbar is not properly sized
>
> import pylab as p
> p.imshow(p.rand(5,3))
> p.colorbar()
> p.savefig('test.svg')g
> p.show()
>
> This problem appeared before and after Steve's application of
> Norbert's PNG patch (thanks's Norbert!) so it looks like
> something
> else is to blame.
One problem with the colorbar is that the png file "im.write_png
(filename)" creates is upside down, image_demo.py creates an upside down
png too.
I see that the GTK/GDK backend does not use im.write_png() but uses
im.as_str() which has a 'flipud' argument to flip the image.
Is it possible for im.write_png() to take the 'flipud' argument and flip
the image for the SVG backend?
The name im.as_str() is a bit vague - what kind of string? Something
like im.as_rgba_str() would make it a bit clearer.
Steve
Send instant messages to your online friends http://au.messenger.yahoo.com
|
|
From: <seb...@fr...> - 2005-08-01 20:25:36
|
Thank you, Seb |
|
From: John H. <jdh...@ac...> - 2005-08-01 16:28:35
|
In some cases, there appears to be a bug in SVG image handling. For
example, the image in the colorbar is not properly sized
import pylab as p
p.imshow(p.rand(5,3))
p.colorbar()
p.savefig('test.svg')g
p.show()
This problem appeared before and after Steve's application of
Norbert's PNG patch (thanks's Norbert!) so it looks like something
else is to blame. See also contourf_demo, in which SVG appears broken
in a perhaps unrelated way.
On the subject, Steve asked offlist whether Agg could write to a file
object rather than disc, which obviate the need to create a temporary
PNG which is subsequently embedded in the SVG file.
I tried this several months ago. The relevant code is src/_image.cpp
Image::write_png where we do
std::string fileName = Py::String(args[0]);
const char *file_name = fileName.c_str();
FILE *fp;
png_structp png_ptr;
fp = fopen(file_name, "wb");
...snip...
png_init_io(png_ptr, fp);
At one point I tried to figure out how to make this work with
StringIO, but was stumped because PNG appears to require a file
pointer and StringIO doesn't emulate this at extension code level, as
far as I can see. Anyone know otherwise? Maybe a question for
python-list....
JDH
|
|
From: John H. <jdh...@ac...> - 2005-08-01 15:59:09
|
>>>>> "sebastian" == sebastian rooks <seb...@fr...> writes:
sebastian> Could it be changed such that figaspect takes a float
sebastian> as its argument and the 2 lines to compute arr_ratio
sebastian> are moved from figaspect to matshow before calling
sebastian> figaspect ? (+ change the figaspect doc string) It will
sebastian> make figaspect more general and allow us to create a
sebastian> figure with a given aspect ratio without
sebastian> copying/pasting of nearly all the figaspect machinery.
Good idea -- I overloaded figaspect to do both (it works with either
an array or a number argument). Code is below and in CVS
Checking in lib/matplotlib/figure.py;
/cvsroot/matplotlib/matplotlib/lib/matplotlib/figure.py,v <-- figure.py
new revision: 1.34; previous revision: 1.33
sebastian> 2/ Does anybody intend to add a Patch object to draw
sebastian> polygons with holes (I do not know how to do it) ?
Not presently, but this would be nice.
JDH
def figaspect(arg):
"""
Create a figure with specified aspect ratio. If arg is a number,
use that aspect ratio. If arg is an array, figaspect will
determine the width and height for a figure that would fit array
preserving aspcect ratio. The figure width, height in inches are
returned. Be sure to create an axes with equal with and height,
eg
Example usage:
# make a figure twice as tall as it is wide
w, h = figaspect(2.)
fig = Figure(figsize=(w,h))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.imshow(A, **kwargs)
# make a figure with the proper aspect for an array
A = rand(5,3)
w, h = figaspect(A)
fig = Figure(figsize=(w,h))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.imshow(A, **kwargs)
Thanks to Fernando Perez for this function
"""
isarray = hasattr(arg, 'shape')
# min/max sizes to respect when autoscaling. If John likes the idea, they
# could become rc parameters, for now they're hardwired.
figsize_min = array((4.0,2.0)) # min length for width/height
figsize_max = array((16.0,16.0)) # max length for width/height
#figsize_min = rcParams['figure.figsize_min']
#figsize_max = rcParams['figure.figsize_max']
# Extract the aspect ratio of the array
if isarray:
nr,nc = arg.shape[:2]
arr_ratio = float(nr)/nc
else:
arr_ratio = float(arg)
# Height of user figure defaults
fig_height = rcParams['figure.figsize'][1]
# New size for the figure, keeping the aspect ratio of the caller
newsize = array((fig_height/arr_ratio,fig_height))
# Sanity checks, don't drop either dimension below figsize_min
newsize /= min(1.0,*(newsize/figsize_min))
# Avoid humongous windows as well
newsize /= max(1.0,*(newsize/figsize_max))
# Finally, if we have a really funky aspect ratio, break it but respect
# the min/max dimensions (we don't want figures 10 feet tall!)
newsize = clip(newsize,figsize_min,figsize_max)
return newsize
|
|
From: Fernando P. <Fer...@co...> - 2005-07-29 23:46:00
|
Fernando Perez wrote: > planck[~]> d .matplotlibrc > /home/fperez > -rw-r--r-- 1 fperez 10529 Jul 29 16:53 .matplotlibrc > planck[~]> python -c 'import pylab' > WARNING: Old rc filename ".matplotlibrc" found in working dir > and and renamed to new default rc file name "matplotlibrc" > (no leading"dot"). > planck[~]> d .matplotlibrc > /home/fperez > /bin/ls: .matplotlibrc: No such file or directory > planck[~]> d .matplotlib > /home/fperez > total 16 > -rw-r--r-- 1 fperez 12642 Jul 29 16:53 ttffont.cache > > > The .matplotlibrc file just goes poof! Correct that: it does get renamed to ~/matplotlibrc. I really hope that's not what the original intent was! I imagine the plan was the equivalent of mkdir ~/.matplotlib mv ~/.matplotlibrc ~/.matplotlib/matplotlibrc Cheers, f |
|
From: Fernando P. <Fer...@co...> - 2005-07-29 22:54:45
|
planck[~]> d .matplotlibrc /home/fperez -rw-r--r-- 1 fperez 10529 Jul 29 16:53 .matplotlibrc planck[~]> python -c 'import pylab' WARNING: Old rc filename ".matplotlibrc" found in working dir and and renamed to new default rc file name "matplotlibrc" (no leading"dot"). planck[~]> d .matplotlibrc /home/fperez /bin/ls: .matplotlibrc: No such file or directory planck[~]> d .matplotlib /home/fperez total 16 -rw-r--r-- 1 fperez 12642 Jul 29 16:53 ttffont.cache The .matplotlibrc file just goes poof! Cheers, f |
|
From: Fernando P. <Fer...@co...> - 2005-07-29 20:07:27
|
John Hunter wrote:
> Anyone know of a simple fix for this
>
>
>>python unicode_demo.py -dSVG
>
>
> File "/usr/lib/python2.4/site-packages/matplotlib/backends/backend_svg.py", line 196, in draw_text
> self._svgwriter.write (svg)
> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 136: ordinal not in range(128)
I recently had to fix the same bug for ipython. Here's what my
stumble-in-the-dark approach to unicode bug fixing (no net access at home that
day) produced:
def _str(self,glob,loc):
"""Evaluate to a string in the given globals/locals.
The final output is built by calling str(), but if this fails, the
result is encoded with the instance's codec and error handling policy,
via a call to out.encode(self.codec,self.encoding_errors)"""
result = []
app = result.append
for live, chunk in self.chunks:
if live: app(str(eval(chunk,glob,loc)))
else: app(chunk)
out = ''.join(result)
try:
return str(out)
except UnicodeError:
return out.encode(self.codec,self.encoding_errors)
where the codec stuff is set via:
Optional arguments:
- codec('utf_8'): a string containing the name of a valid Python
codec.
- encoding_errors('backslashreplace'): a string with a valid error
handling
policy. See the codecs module documentation for details.
These are used to encode the format string if a call to str() fails on
the expanded result."""
if not isinstance(format,basestring):
raise TypeError, "needs string initializer"
self.format = format
self.codec = codec
self.encoding_errors = encoding_errors
This is all in ipython's Itpl.py module, in case you want to look closer (the
crash was there b/c that's the machinery used for prompt printing).
cheers,
f
|
|
From: M. <ja...@fc...> - 2005-07-29 19:13:30
|
John Hunter wrote: > > Anyone know of a simple fix for this > >> python unicode_demo.py -dSVG > > File > "/usr/lib/python2.4/site-packages/matplotlib/backends/backend_svg.py", > line 196, in draw_text > self._svgwriter.write (svg) > UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in > position 136: ordinal not in range(128) I found this link very useful to understand this type of problems: http://evanjones.ca/python-utf8.html -- José Abílio |
|
From: John H. <jdh...@ac...> - 2005-07-29 14:57:01
|
Anyone know of a simple fix for this
> python unicode_demo.py -dSVG
File "/usr/lib/python2.4/site-packages/matplotlib/backends/backend_svg.py", line 196, in draw_text
self._svgwriter.write (svg)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 136: ordinal not in range(128)
|
|
From: <seb...@fr...> - 2005-07-28 15:15:48
|
Hi,
First of all thank you for this great package.
1/
The matshow function computes the aspect ratio of the figure with:
in matplotlib/pylab.py
def matshow(*args,**kw):
...
# Extract actual aspect ratio of array and make appropriately sized f=
igure
w,h =3D figaspect(arr)
...
before displaying it.
figaspect takes the array as an argument and compute its aspect ratio wit=
h:
in matplotlib/figure.py
def figaspect(arr):
...
# Extract the aspect ratio of the array
nr,nc =3D arr.shape[:2]
arr_ratio =3D float(nr)/nc
...
Could it be changed such that figaspect takes a float as its argument and=
the 2
lines to compute arr_ratio are moved from figaspect to matshow before cal=
ling
figaspect ? (+ change the figaspect doc string)
It will make figaspect more general and allow us to create a figure with =
a given
aspect ratio without copying/pasting of nearly all the figaspect machiner=
y.
2/
Does anybody intend to add a Patch object to draw polygons with holes (I =
do not
know how to do it) ?
Thank you,
Seb
|
|
From: Jamil K. <jam...@ca...> - 2005-07-27 04:05:58
|
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.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
#!/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
=20
raw_value =3D -4.0
raw_limits =3D [-10.0,10.0,5,1]
raw_zones =3D [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
s_length =3D 0.3
p_length =3D 2.0
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
=20
rect =3D [(0.2/fig_width), (0.5/fig_height),
(p_length/fig_width), (s_length/fig_height)]
=20
meter =3D H_Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
meter.set_axis_off()
fig.add_axes(meter)
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): =20
Axes.__init__(self, *args, **kwargs)
#Perform Checking
if( raw_limits[0] =3D=3D raw_limits[1] ):
raise ValueError('identical_limits_exception: %s' % =
raw_limits)
if( raw_limits[1] > raw_limits[0] ):
self.graph_positive =3D True
else: #Swap the limits around
self.graph_positive =3D False
raw_limits[0], raw_limits[1] =3D raw_limits[1] =3D =
raw_limits[0]
=20
if not( ((raw_limits[2]/raw_limits[3]) % 1.0) * raw_limits[3] =
=3D=3D 0 ): #There must be an integer number of minor ticks for each =
major tick
raise ValueError('bad_tick_spacing_exception')
if( raw_limits[2] <=3D 0 or raw_limits[3] <=3D 0 or =
raw_limits[2] < raw_limits[3] or raw_limits[3] > =
abs(raw_limits[1]-raw_limits[0]) ):
raise ValueError('bad_limits_exception:%s' % raw_limits)
for zone in raw_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > =
zone[0]
zone[0], zone[1] =3D zone[1] =3D zone[0]
if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] =
):
raise ValueError('bad_zone_exception'%zone)
if( zone[0] < raw_limits[0] ):
zone[0] =3D raw_limits[0]
if( zone[1] > raw_limits[1] ):
zone[1] =3D raw_limits[1]
=20
#Adjust the scaling
self.scaled_limits =3D []
for limit in raw_limits:
self.scaled_limits.append( limit * p_length / =
(raw_limits[1]-raw_limits[0]))
=20
#Stuff all of the variables into self.
self.vertical =3D vertical
self.raw_values =3D raw_values
self.raw_limits =3D raw_limits
self.raw_zones =3D raw_zones
self.attribute_name =3D attribute_name
self.field_names =3D field_names
self.file_name =3D file_name
self.resolution =3D resolution
self.p_length =3D p_length
self.s_length =3D s_length
=20
#Draw the meter
self.graph_center =3D =
((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=3D12, va=3D'bottom', ha=3D'center')
else:
self.text( self.graph_center, self.s_length+0.05, =
self.attribute_name, size=3D12, va=3D'bottom', ha=3D'center')
=20
def draw_bar( self, zone, border):
if( border ):
start =3D self.scaled_limits[0]
end =3D self.scaled_limits[1]
else:
start =3D (zone[0] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0]))
end =3D (zone[1] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0]))
colour =3D zone[2]
=20
if( not self.graph_positive ):
start =3D -start
end =3D -end
=20
s_vect =3D [ 0.0, 0.0, self.s_length, self.s_length ]
p_vect =3D [ start, end, end, start ]
=20
if( border ):
#Close the loop
p_vect.append(start)
s_vect.append(0.0)
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
p =3D self.plot(p_vect, s_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
if( self.vertical ):
p =3D self.fill(s_vect, p_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
else:
p =3D self.fill(p_vect, s_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
def draw_dividers( self ):
i =3D 1
num_fields =3D len(self.raw_values)
while( i < num_fields ):
s_vect =3D [
(i * self.s_length)/num_fields,
(i * self.s_length)/num_fields,
]
p_vect =3D [
self.scaled_limits[0],
self.scaled_limits[1],
]
if( self.vertical ):
self.plot(s_vect, p_vect, 'b-', color=3D'black', =
linewidth=3D1.0)
else:
self.plot(p_vect, s_vect, 'b-', color=3D'black', =
linewidth=3D1.0)
i +=3D 1=20
=20
def draw_needle( self ):
i =3D 0 =20
for raw_value in self.raw_values:
=20
if( raw_value =3D=3D 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=3D10, va=3D'top', ha=3D'right', =
rotation=3D45)
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=3D10, va=3D'center', ha=3D'right')
else:
=20
#Clamp the value to the limits
value =3D raw_value * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
if( raw_value < self.raw_limits[0] ):
value =3D self.raw_limits[0] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
if( raw_value > self.raw_limits[1] ):
value =3D self.raw_limits[1] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
=20
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=3D10, va=3D'top', =
ha=3D'right', rotation=3D45)=20
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=3D10, va=3D'center', =
ha=3D'right')=20
=20
if( not self.graph_positive ):
value =3D -value
=20
s_vect =3D [
((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 =3D [
value,
value - 0.05,
value,
value + 0.05,
]
=20
if( self.vertical ):
self.fill(s_vect, p_vect, 'b', alpha=3D0.4)
else:
self.fill(p_vect, s_vect, 'b', alpha=3D0.4)
i +=3D 1
=20
=20
def draw_ticks( self ):
num_fields =3D len(self.raw_values)
if( self.graph_positive ):
offset =3D self.scaled_limits[0]
else:
offset =3D self.scaled_limits[1]
i =3D 0
j =3D self.raw_limits[0]
while( i*self.scaled_limits[3] + self.scaled_limits[0] <=3D =
self.scaled_limits[1] ):
if( i % (self.scaled_limits[2]/self.scaled_limits[3]) =3D=3D =
0):
tick_length =3D self.s_length
if( self.vertical ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( -0.05, offset, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'right')=20
else:
self.text( -0.05, offset, "%d" % int(j), =
size=3D10, va=3D'center', ha=3D'right')
else:
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( offset, -0.05, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( offset, -0.05, "%d" % int(j), =
size=3D10, va=3D'top', ha=3D'center')=20
j +=3D self.raw_limits[2]
else:
tick_length =3D (self.s_length/num_fields) * 0.2
=20
s_vect =3D [ 0.0, tick_length ]
p_vect =3D [ offset, offset ]
=20
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
else:
p =3D self.plot(p_vect, s_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
i +=3D 1
if( self.graph_positive ):
offset +=3D self.scaled_limits[3]
else:
offset -=3D self.scaled_limits[3]
=20
if( i % (self.scaled_limits[2]/self.scaled_limits[3]) =3D=3D 0):
if( self.vertical ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( -0.01, offset, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( -0.01, offset, "%d" % int(j), size=3D10, =
va=3D'top', ha=3D'center')=20
else:
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( offset, -0.1, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( offset, -0.1, "%d" % int(j), size=3D10, =
va=3D'top', ha=3D'center')=20
=20
def make_widget( vertical, raw_values, raw_limits, raw_zones, =
attribute_name, field_names, file_name, resolution=3D72 ):
from pylab import figure, show, savefig
=20
p_length =3D 4.0 # Length of the Primary axis
s_length =3D 0.3 * len(raw_values) # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 1.6
fig_width =3D s_length + 1.1
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.9/fig_width), (1.3/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(vertical, raw_values,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,=20
p_length, s_length,
fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[]
)
else:
fig_height =3D s_length + 0.5
fig_width =3D p_length + 1.9
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(1.7/fig_width), (0.2/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(vertical, raw_values,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,
p_length, s_length,
fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure( file_name,dpi=3Dresolution ) =20
=20
=20
#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)
''' =20
=20
if __name__=3D=3D'__main__':
from pylab import figure, show, savefig
=20
vertical =3D False =20
=20
raw_values =3D [-3.0, 6.0, None, 0.25]
raw_limits =3D [-10.0,10.0,5,1]
raw_zones =3D [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
field_names =3D ['WLL to LAS','LAS to WLL','WLL to LAS','LAS to =
WLL']
=20
p_length =3D 4.0 # Length of the Primary axis
s_length =3D 0.3 * len(raw_values) # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 1.6
fig_width =3D s_length + 1.1
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.9/fig_width), (1.3/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
else:
fig_height =3D s_length + 0.5
fig_width =3D p_length + 1.9
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(1.7/fig_width), (0.2/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure('multimeter',dpi=3D72)
'''
|
|
From: Jamil K. <jam...@ca...> - 2005-07-27 04:04:46
|
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.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
#!/usr/bin/env python
'''
The Log_Gauge widget draws a semi-circular gauge. You supply limits,
shaded regions, names and the current value, and invoke it like this:
from pylab import figure, show
raw_value =3D -4.0
limits =3D [ left, right ]
zone_colour =3D [[-1.0,0.0,'r'],[0.0,0.5,'y'],[0.5,1.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
graph_height =3D 1.6
graph_width =3D 2.4
fig_height =3D graph_height
fig_width =3D graph_width
fig =3D figure(figsize=3D(fig_width, fig_height ))
=20
rect =3D [(0.0/fig_width), (0.2/fig_height),
(graph_width/fig_width), (graph_height/fig_height)]
=20
gauge =3D Gauge(fig, rect,
xlim=3D( -0.1, graph_width+0.1 ),
ylim=3D( -0.4, graph_height+0.1 ),
xticks=3D[],
yticks=3D[],
)
gauge.set_axis_off()
fig.add_axes(gauge)
show()
=20
NOTE: The limits you specify must be of this form
for any value of 'n': 1.0*10^n
'''
from __future__ import division
from matplotlib.figure import Figure
from matplotlib.axes import Axes
import math
import types
from math import pi
class Log_Gauge(Axes):
def __init__(self, raw_value, raw_limits, raw_zones, attribute_name, =
field_names, file_name, resolution, x_length, y_length, *args, =
**kwargs):
Axes.__init__(self, *args, **kwargs)
=20
#Perform Checking
if( raw_limits[0] =3D=3D raw_limits[1] ):
raise ValueError('identical_limits_exception: %s' % =
raw_limits)
if( raw_limits[1] > raw_limits[0] ):
self.graph_positive =3D True
else: #Swap the limits around
self.graph_positive =3D False
raw_limits[0], raw_limits[1] =3D raw_limits[1] =3D =
raw_limits[0]
=20
if not( math.log10(raw_limits[0]) % 1.0 =3D=3D 0 and =
math.log10(raw_limits[1]) % 1.0 =3D=3D 0 ):
raise ValueError('bad_limits_exception:%s' % raw_limits)
=20
for zone in raw_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > =
zone[0]
zone[0], zone[1] =3D zone[1], zone[0]
if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] ):
raise ValueError('bad_zone_exception' % zone)
if( zone[0] < raw_limits[0] ):
zone[0] =3D raw_limits[0]
if( zone[1] > raw_limits[1] ):
zone[1] =3D raw_limits[1]
=20
#Stuff all of the variables into self.
self.raw_value =3D raw_value
self.raw_limits =3D raw_limits
self.raw_zones =3D raw_zones
self.attribute_name =3D attribute_name
self.field_names =3D field_names
self.file_name =3D file_name
self.resolution =3D resolution
self.x_length =3D x_length
self.y_length =3D y_length
=20
=20
#Draw the arch
for zone in raw_zones:
self.draw_arch( zone, False )
self.draw_arch( None, True )
self.draw_ticks()
self.draw_needle()
self.draw_bounding_box()
self.text(0.0, 0.3, attribute_name, size=3D10, va=3D'center', =
ha=3D'center')
=20
#The black dot
p =3D self.plot([0.0],[0.0],'.', color=3D'#000000') =20
=20
def draw_arch( self, zone, border ):
if( border ):
start =3D self.raw_limits[0]
end =3D self.raw_limits[1]
else:
start =3D zone[0]
end =3D zone[1]
colour =3D zone[2]
=20
x_vect =3D []
y_vect =3D []
if( self.graph_positive ):
start_value =3D int(180 - (start - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
end_value =3D int(180 - (end - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
else:
start_value =3D int( (end - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
end_value =3D int( (start - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
=20
=20
if( self.graph_positive ):
start_value =3D (math.log10(start) - =
math.log10(self.raw_limits[1])) * 180.00 / =
-(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
end_value =3D (math.log10(end) - =
math.log10(self.raw_limits[1])) * 180.00 / =
-(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
else:
start_value =3D (math.log10(end) - =
math.log10(self.raw_limits[0])) * 180.00 / =
+(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
end_value =3D (math.log10(start) - =
math.log10(self.raw_limits[0])) * 180.00 / =
+(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
=20
#Draw the arch
theta =3D start_value
radius =3D 0.85
while (theta >=3D end_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta -=3D 1
=20
theta =3D end_value
radius =3D 1.0
while (theta <=3D start_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta +=3D 1
=20
if( border ):
#Close the loop
x_vect.append(-0.85)
y_vect.append(0.0)
=20
p =3D self.plot(x_vect, y_vect, 'b-', color=3D'black', =
linewidth=3D1.0)
else:
p =3D self.fill(x_vect, y_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
=20
=20
def draw_needle( self ):
x_vect =3D []
y_vect =3D []
=20
if self.raw_value =3D=3D None:
self.text(0.0, 0.4, "N/A", size=3D10, va=3D'bottom', =
ha=3D'center')
else:
self.text(0.0, 0.4, "%.2f" % self.raw_value, size=3D10, =
va=3D'bottom', ha=3D'center')
=20
#Clamp the value to the limits
if( self.raw_value < self.raw_limits[0] ):
self.raw_value =3D self.raw_limits[0]
if( self.raw_value > self.raw_limits[1] ):
self.raw_value =3D self.raw_limits[1]
=20
theta =3D 0
length =3D 0.95
if( self.graph_positive ):
angle =3D (math.log10(self.raw_value) - =
math.log10(self.raw_limits[1])) * 180.00 / =
-(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
else:
angle =3D (math.log10(self.raw_value) - =
math.log10(self.raw_limits[0])) * 180.00 / =
+(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
=20
while (theta <=3D 270):
x_vect.append( length * math.cos((theta + angle) * =
(pi/180)) )
y_vect.append( length * math.sin((theta + angle) * =
(pi/180)) )
length =3D 0.05
theta +=3D 90
p =3D self.fill(x_vect, y_vect, 'b', alpha=3D0.4)
=20
=20
=20
def draw_ticks( self ):
if( self.graph_positive ):
angle =3D 180.0
else:
angle =3D 0.0
=20
i =3D self.raw_limits[0]
step =3D self.raw_limits[0]
x_vect =3D []
y_vect =3D []
while( i < self.raw_limits[1] ):
while( i < (step * 10) ):
x_vect =3D []
y_vect =3D []
value =3D math.log10(i)
if( self.graph_positive ):
angle =3D (value - math.log10(self.raw_limits[1])) * =
180.00 / -(math.log10(self.raw_limits[1]) - =
math.log10(self.raw_limits[0]))
else:
angle =3D (value - math.log10(self.raw_limits[0])) * =
180.00 / +(math.log10(self.raw_limits[1]) - =
math.log10(self.raw_limits[0]))
x_pos =3D 1.1 * math.cos( angle * (pi/180.0))
y_pos =3D 1.1 * math.sin( angle * (pi/180.0))
mantissa =3D int(i / math.pow(10, =
math.ceil(math.log10(i))-1))
if( mantissa =3D=3D 10 or mantissa =3D=3D 1 ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( x_pos, y_pos, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90))
else:
self.text( x_pos, y_pos, "%d" % int(j), =
size=3D10, va=3D'center', ha=3D'center', rotation=3D(angle - 90))
tick_length =3D 0.15
else:
tick_length =3D 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 =3D self.plot(x_vect, y_vect, 'b-', linewidth=3D1, =
alpha=3D0.4, color=3D"black")
=20
i +=3D step
i =3D step * 10
step =3D step * 10
i =3D self.raw_limits[1]
value =3D math.log10(i)
if( self.graph_positive ):
angle =3D (value - math.log10(self.raw_limits[1])) * 180.00 =
/ -(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
else:
angle =3D (value - math.log10(self.raw_limits[0])) * 180.00 =
/ +(math.log10(self.raw_limits[1]) - math.log10(self.raw_limits[0]))
x_pos =3D 1.1 * math.cos( angle * (pi/180.0))
y_pos =3D 1.1 * math.sin( angle * (pi/180.0))
mantissa =3D int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa =3D=3D 10 ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( x_pos, y_pos, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90))
else:
self.text( x_pos, y_pos, "%d" % int(j), size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90)) =20
=20
=20
=20
def draw_bounding_box( self ):
x_vect =3D [
self.x_length/2,
self.x_length/2,
-self.x_length/2,
-self.x_length/2,
self.x_length/2,
]
y_vect =3D [
-0.1,
self.y_length,
self.y_length,
-0.1,
-0.1,
]
p =3D self.plot(x_vect, y_vect, 'r-', linewidth=3D0)
=20
=20
=20
def make_widget( raw_value, raw_limits, raw_zones, attribute_name, =
field_names, file_name, resolution=3D72 ): =20
from pylab import figure, show, savefig
x_length =3D 2.4 # Length of the Primary axis
y_length =3D 1.6 # Length of the Secondary axis
=20
fig_height =3D y_length
fig_width =3D x_length
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.0/fig_width), (0.2/fig_height), (x_length/fig_width), =
(y_length/fig_height)]
gauge =3D Log_Gauge( raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,
x_length, y_length,
fig, rect,
xlim=3D( -0.1, x_length+0.1 ),
ylim=3D( -0.4, y_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
gauge.set_axis_off()
fig.add_axes(gauge)
# show()
fig.canvas.print_figure( file_name,dpi=3Dresolution ) =20
=20
=20
#make_widget( 0.01, [0.001,10.0], =
[[0.001,0.01,'r'],[0.01,0.1,'y'],[0.1,10.0,'g']], "Rx MOS (24h)", ['WLL =
to LAS','LAS to WLL','WLL to LAS','LAS to WLL'], 'log_gauge.png', 100)
=20
=20
=20
''' =20
if __name__=3D=3D'__main__':
from pylab import figure, show
=20
raw_value =3D -4.0
limits =3D [0.0001,1.0]
zone_colour =3D [[0.0001,0.001,'r'],[0.001,0.1,'y'],[0.1,1.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
graph_height =3D 1.6
graph_width =3D 2.4
fig_height =3D graph_height
fig_width =3D graph_width
fig =3D figure( figsize=3D(fig_width, fig_height) )
=20
rect =3D [(0.0/fig_width), (0.2/fig_height),
(graph_width/fig_width), (graph_height/fig_height)]
=20
gauge =3D Log_Gauge(fig, rect,
xlim=3D( -0.1, graph_width+0.1 ),
ylim=3D( -0.4, graph_height+0.1 ),
xticks=3D[],
yticks=3D[],
)
gauge.set_axis_off()
fig.add_axes(gauge)
=20
#show()
fig.canvas.print_figure('log_gauge',dpi=3D72)
'''
=20
=20
|
|
From: Jamil K. <jam...@ca...> - 2005-07-27 04:04:16
|
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.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
#!/usr/bin/env python
"""
The Gauge widget draws a semi-circular gauge. You supply raw_limits,
shaded regions, names and the current value, and invoke it like this:
from pylab import figure, show
raw_value =3D -4.0
raw_limits =3D [-1.0,1.0,1,0.1]
raw_zones =3D [[-1.0,0.0,'r'],[0.0,0.5,'y'],[0.5,1.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
graph_height =3D 1.6
graph_width =3D 2.4
fig_height =3D graph_height
fig_width =3D graph_width
fig =3D figure(figsize=3D(fig_width, fig_height ))
=20
rect =3D [(0.0/fig_width), (0.2/fig_height),
(graph_width/fig_width), (graph_height/fig_height)]
=20
gauge =3D Gauge(fig, rect,
xlim=3D( -0.1, graph_width+0.1 ),
ylim=3D( -0.4, graph_height+0.1 ),
xticks=3D[],
yticks=3D[],
)
gauge.set_axis_off()
fig.add_axes(gauge)
show()
"""
from __future__ import division
from matplotlib.figure import Figure
from matplotlib.axes import Axes
import math
import types
from math import pi
=20
class Gauge(Axes):
def __init__(self, raw_value, raw_limits, raw_zones, attribute_name, =
field_names, file_name, resolution, x_length, y_length, *args, =
**kwargs):
Axes.__init__(self, *args, **kwargs)
#Perform Checking
if( raw_limits[0] =3D=3D raw_limits[1] ):
raise ValueError('identical_raw_limits_exception: =
%s'%raw_limits)
if( raw_limits[1] > raw_limits[0] ):
self.graph_positive =3D True
else: #Swap the raw_limits around
self.graph_positive =3D False
raw_limits[0], raw_limits[1] =3D raw_limits[1] =3D =
raw_limits[0]
#There must be an integer number of minor ticks for each major =
tick
if not( ((raw_limits[2]/raw_limits[3]) % 1.0) * raw_limits[3] =
=3D=3D 0 ): =20
raise ValueError('bad_tick_spacing_exception')
if( raw_limits[2] <=3D 0 or
raw_limits[3] <=3D 0 or
raw_limits[2] < raw_limits[3] or
raw_limits[3] > abs(raw_limits[1]-raw_limits[0]) ):
raise ValueError('bad_raw_limits_exception:%s' % raw_limits)
for zone in raw_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > =
zone[0]
zone[0], zone[1] =3D zone[1], zone[0]
if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] ):
raise ValueError('bad_zone_exception'%zone)
if( zone[0] < raw_limits[0] ):
zone[0] =3D raw_limits[0]
if( zone[1] > raw_limits[1] ):
zone[1] =3D raw_limits[1]
#Stuff all of the variables into self.
self.raw_value =3D raw_value
self.raw_limits =3D raw_limits
self.raw_zones =3D raw_zones
self.attribute_name =3D attribute_name
self.field_names =3D field_names
self.file_name =3D file_name
self.resolution =3D resolution
self.x_length =3D x_length
self.y_length =3D y_length
=20
=20
#Draw the gauge
for zone in raw_zones:
self.draw_arch( zone, False )
self.draw_arch( None, True )
self.draw_ticks()
self.draw_needle()
self.draw_bounding_box()
self.text(0.0, 0.2, self.attribute_name, size=3D10, =
va=3D'bottom', ha=3D'center')
#The black dot
p =3D self.plot([0.0],[0.0],'.', color=3D'#000000')
def draw_arch( self, zone, border ):
if( border ):
start =3D self.raw_limits[0]
end =3D self.raw_limits[1]
else:
start =3D zone[0]
end =3D zone[1]
colour =3D zone[2]
=20
x_vect =3D []
y_vect =3D []
if( self.graph_positive ):
start_value =3D int(180 - (start - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
end_value =3D int(180 - (end - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
else:
start_value =3D int( (end - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
end_value =3D int( (start - self.raw_limits[0]) * =
(180.0/(self.raw_limits[1]-self.raw_limits[0])))
#Draw the arch
theta =3D start_value
radius =3D 0.85
while (theta >=3D end_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta -=3D 1
theta =3D end_value
radius =3D 1.0
while (theta <=3D start_value):
x_vect.append( radius * math.cos(theta * (pi/180)) )
y_vect.append( radius * math.sin(theta * (pi/180)) )
theta +=3D 1
if( border ):
#Close the loop
x_vect.append(-0.85)
y_vect.append(0.0)
p =3D self.plot(x_vect, y_vect, 'b-', color=3D'black', =
linewidth=3D1.0)
else:
p =3D self.fill(x_vect, y_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
def draw_needle( self ):
x_vect =3D []
y_vect =3D []
if self.raw_value =3D=3D None:
self.text(0.0, 0.4, "N/A", size=3D10, va=3D'bottom', =
ha=3D'center')
else:
self.text(0.0, 0.4, "%.2f" % self.raw_value, size=3D10, =
va=3D'bottom', ha=3D'center')
#Clamp the value to the raw_limits
if( self.raw_value < self.raw_limits[0] ):
self.raw_value =3D self.raw_limits[0]
if( self.raw_value > self.raw_limits[1] ):
self.raw_value =3D self.raw_limits[1]
theta =3D 0
length =3D 0.95
if( self.graph_positive ):
angle =3D 180.0 - (self.raw_value - self.raw_limits[0]) =
*(180.0/abs(self.raw_limits[1]-self.raw_limits[0]))
else:
angle =3D (self.raw_value - self.raw_limits[0]) =
*(180.0/abs(self.raw_limits[1]-self.raw_limits[0]))
while (theta <=3D 270):
x_vect.append( length * math.cos((theta + angle) * =
(pi/180)) )
y_vect.append( length * math.sin((theta + angle) * =
(pi/180)) )
length =3D 0.05
theta +=3D 90
p =3D self.fill(x_vect, y_vect, 'b', alpha=3D0.4)
def draw_ticks( self ):
if( self.graph_positive ):
angle =3D 180.0
else:
angle =3D 0.0
i =3D 0
j =3D self.raw_limits[0]
while( i*self.raw_limits[3] + self.raw_limits[0] <=3D =
self.raw_limits[1] ):
x_vect =3D []
y_vect =3D []
if( i % (self.raw_limits[2]/self.raw_limits[3]) =3D=3D 0 ):
x_pos =3D 1.1 * math.cos( angle * (pi/180.0))
y_pos =3D 1.1 * math.sin( angle * (pi/180.0))
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( x_pos, y_pos, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90))
else:
self.text( x_pos, y_pos, "%d" % int(j), size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90))
tick_length =3D 0.15
j +=3D self.raw_limits[2]
else:
tick_length =3D 0.05
i +=3D 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 =3D self.plot(x_vect, y_vect, 'b-', linewidth=3D1, =
alpha=3D0.4, color=3D"black")
if( self.graph_positive ):
angle -=3D self.raw_limits[3] * =
(180.0/abs(self.raw_limits[1]-self.raw_limits[0]))
else:
angle +=3D self.raw_limits[3] * =
(180.0/abs(self.raw_limits[1]-self.raw_limits[0]))
if( i % (self.raw_limits[2]/self.raw_limits[3]) =3D=3D 0 ):
x_pos =3D 1.1 * math.cos( angle * (pi/180.0))
y_pos =3D 1.1 * math.sin( angle * (pi/180.0))
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( x_pos, y_pos, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90))
else:
self.text( x_pos, y_pos, "%d" % int(j), size=3D10, =
va=3D'center', ha=3D'center', rotation=3D(angle - 90)) =20
def draw_bounding_box( self ):
x_vect =3D [
self.x_length/2,
self.x_length/2,
-self.x_length/2,
-self.x_length/2,
self.x_length/2,
]
y_vect =3D [
-0.1,
self.y_length,
self.y_length,
-0.1,
-0.1,
]
p =3D self.plot(x_vect, y_vect, 'r-', linewidth=3D0)
def make_widget( raw_value, raw_limits, raw_zones, attribute_name, =
field_names, file_name, resolution=3D72 ):
from pylab import figure, show, savefig
=20
x_length =3D 2.4 # Length of the Primary axis
y_length =3D 1.6 # Length of the Secondary axis
=20
fig_height =3D y_length
fig_width =3D x_length
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.0/fig_width), (0.2/fig_height), (x_length/fig_width), =
(y_length/fig_height)]
gauge =3D Gauge( raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,
x_length, y_length,
fig, rect,
xlim=3D( -0.1, x_length+0.1 ),
ylim=3D( -0.4, y_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
gauge.set_axis_off()
fig.add_axes(gauge)
# show()
fig.canvas.print_figure( file_name,dpi=3Dresolution ) =20
=20
=20
#make_widget( -3.0, [-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'], 'gauge.png', 100)
=20
=20
'''
if __name__=3D=3D'__main__':
from pylab import figure, show
=20
raw_value =3D -4.0
raw_limits =3D [-1.0,1.0,1,0.1]
raw_zones =3D [[-1.0,0.0,'r'],[0.0,0.5,'y'],[0.5,1.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
graph_height =3D 1.6
graph_width =3D 2.4
fig_height =3D graph_height
fig_width =3D graph_width
fig =3D figure( figsize=3D(fig_width, fig_height) )
=20
rect =3D [(0.0/fig_width), (0.2/fig_height),
(graph_width/fig_width), (graph_height/fig_height)]
=20
gauge =3D Gauge(fig, rect,
xlim=3D( -0.1, graph_width+0.1 ),
ylim=3D( -0.4, graph_height+0.1 ),
xticks=3D[],
yticks=3D[],
)
gauge.set_axis_off()
fig.add_axes(gauge)
show()
fig.canvas.print_figure('gauge',dpi=3D72)
=20
'''
=20
|
|
From: Jamil K. <jam...@ca...> - 2005-07-27 04:03:16
|
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.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
#!/usr/bin/env python
"""
The Log_Meter widget draws a logarithmic 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
=20
raw_value =3D -4.0
raw_limits =3D [-10.0,10.0,5,1]
raw_zones =3D [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
s_length =3D 0.3
p_length =3D 2.0
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
=20
rect =3D [(0.2/fig_width), (0.5/fig_height),
(p_length/fig_width), (s_length/fig_height)]
=20
meter =3D Log_Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
meter.set_axis_off()
fig.add_axes(meter)
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_value, 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] =3D=3D raw_limits[1] ):
raise ValueError('identical_limits_exception: %s' % =
raw_limits)
if( raw_limits[1] > raw_limits[0] ):
self.graph_positive =3D True
else: #Swap the limits around
self.graph_positive =3D False
raw_limits[0], raw_limits[1] =3D raw_limits[1] =3D =
raw_limits[0]
=20
if not( math.log10(raw_limits[0]) % 1.0 =3D=3D 0 and =
math.log10(raw_limits[1]) % 1.0 =3D=3D 0 ):
raise ValueError('bad_limits_exception:%s' % raw_limits)
for zone in raw_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > =
zone[0]
zone[0], zone[1] =3D zone[1] =3D zone[0]
if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] =
):
raise ValueError('bad_zone_exception'%zone)
if( zone[0] < raw_limits[0] ):
zone[0] =3D raw_limits[0]
if( zone[1] > raw_limits[1] ):
zone[1] =3D raw_limits[1]
=20
=20
=20
#Stuff all of the variables into self.
self.vertical =3D vertical
self.raw_value =3D raw_value
self.raw_limits =3D raw_limits
self.raw_zones =3D raw_zones
self.attribute_name =3D attribute_name
self.field_names =3D field_names
self.file_name =3D file_name
self.resolution =3D resolution
self.p_length =3D p_length
self.s_length =3D s_length
=20
#Draw the meter
self.graph_center =3D =
((math.log10(self.raw_limits[0])+math.log10(self.raw_limits[1]))/2)
for zone in raw_zones:
self.draw_bar( zone, False)
self.draw_bar( None, True)
self.draw_ticks()
self.draw_needle()
if( vertical ):
self.text( self.s_length/2, =
math.log10(self.raw_limits[0])-0.2, self.attribute_name, size=3D12, =
va=3D'top', ha=3D'center')
else:
self.text( self.graph_center, self.s_length+0.25, =
self.attribute_name, size=3D12, va=3D'bottom', ha=3D'center')
=20
def draw_bar( self, zone, border ):
if( border ):
start =3D self.raw_limits[0]
end =3D self.raw_limits[1]
else:
start =3D zone[0]
end =3D zone[1]
colour =3D zone[2]
=20
if( self.graph_positive ):
start =3D math.log10(start)
end =3D math.log10(end)
else:
start =3D -math.log10(start)
end =3D -math.log10(end)
=20
s_vect =3D [ 0.0, 0.0, self.s_length, self.s_length ]
p_vect =3D [ start, end, end, start ]
=20
if( border ):
#Close the loop
p_vect.append(start)
s_vect.append(0.0)
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
p =3D self.plot(p_vect, s_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
if( self.vertical ):
p =3D self.fill(s_vect, p_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
else:
p =3D self.fill(p_vect, s_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
def draw_needle( self ):
if( self.raw_value =3D=3D None ):
if( self.vertical ):
self.text( (self.s_length + 0.05), self.graph_center, =
"N/A", size=3D10, va=3D'center', ha=3D'left')
else:
self.text( self.graph_center, (self.s_length + 0.05), =
"N/A", size=3D10, va=3D'bottom', ha=3D'center')
else:
#Clamp the value to the limits
value =3D math.log10(self.raw_value)
if( self.raw_value < self.raw_limits[0] ):
value =3D math.log10(self.raw_limits[0])
if( self.raw_value > self.raw_limits[1] ):
value =3D math.log10(self.raw_limits[1])
=20
if( self.vertical ):
self.text( (self.s_length + 0.05), value, "%.2f" % =
self.raw_value, size=3D10, va=3D'center', ha=3D'left')=20
else:
self.text( value, (self.s_length + 0.05), "%.2f" % =
self.raw_value, size=3D10, va=3D'bottom', ha=3D'center')=20
=20
if( not self.graph_positive ):
value =3D -value
s_vect =3D [ self.s_length/2, self.s_length, self.s_length ]
p_vect =3D [ value + 0.00, value - 0.1, value + 0.1 ]
=20
if( self.vertical ):
self.fill(s_vect, p_vect, 'black')
else:
self.fill(p_vect, s_vect, 'black')
=20
=20
def draw_ticks( self ):
i =3D self.raw_limits[0]
step =3D self.raw_limits[0]
while( i < self.raw_limits[1] ):
while( i < (step * 10) ):
value =3D math.log10(i)
if( not self.graph_positive ):
value =3D -value
mantissa =3D int(i / math.pow(10, =
math.ceil(math.log10(i))-1))
if( mantissa =3D=3D 10 or mantissa =3D=3D 1 ):
if( self.vertical ):
self.text( -0.05, value, "%g" % i, size=3D10, =
va=3D'center', ha=3D'right')
else: =20
self.text( value, -0.05, "%g" % i, size=3D10, =
va=3D'top', ha=3D'center')=20
tick_length =3D self.s_length
else:
tick_length =3D self.s_length * 0.2
s_vect =3D [ 0.0, tick_length ]
p_vect =3D [ value, value ]
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
else:
p =3D self.plot(p_vect, s_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
i +=3D step
i =3D step * 10
step =3D step * 10
i =3D self.raw_limits[1]
value =3D math.log10(i)
if( not self.graph_positive ):
value =3D -value
mantissa =3D int(i / math.pow(10, math.ceil(math.log10(i))-1))
if( mantissa =3D=3D 10 ):
if( self.vertical ):
self.text( -0.05, value, "%g" % i, size=3D10, =
va=3D'center', ha=3D'right')
else: =20
self.text( value, -0.05, "%g" % i, size=3D10, =
va=3D'top', ha=3D'center')=20
=20
=20
def make_widget( vertical, raw_value, raw_limits, raw_zones, =
attribute_name, field_names, file_name, resolution=3D72 ): =20
from pylab import figure, show, savefig
p_length =3D 2.0 # Length of the Primary axis
s_length =3D 0.3 # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 0.6
fig_width =3D s_length + 1.0
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.5/fig_width), (0.4/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(vertical, raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,=20
p_length, s_length,
fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[]
)
else:
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.2/fig_width), (0.5/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(vertical, raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,
p_length, s_length,
fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure( file_name,dpi=3Dresolution ) =20
=20
=20
#make_widget( True, 0.01, [0.001,10.0], =
[[0.001,0.01,'r'],[0.01,0.1,'y'],[0.1,10.0,'g']], "Rx MOS (24h)", ['WLL =
to LAS','LAS to WLL','WLL to LAS','LAS to WLL'], 'log_meter.png', 100)
=20
''' =20
=20
if __name__=3D=3D'__main__':
from pylab import figure, show, savefig
=20
vertical =3D True =20
=20
raw_value =3D 0.1
raw_limits =3D [0.0001,10.0,5,1]
raw_zones =3D [[0.0001,0.001,'r'],[0.001,0.1,'y'],[0.1,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
p_length =3D 2.0 # Length of the Primary axis
s_length =3D 0.3 # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 0.6
fig_width =3D s_length + 1.0
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.5/fig_width), (0.4/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
else:
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.2/fig_width), (0.5/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure('log_meter',dpi=3D72)
'''
|
|
From: Jamil K. <jam...@ca...> - 2005-07-27 04:02:36
|
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.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
#!/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
=20
raw_value =3D -4.0
raw_limits =3D [-10.0,10.0,5,1]
raw_zones =3D [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
s_length =3D 0.3
p_length =3D 2.0
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
=20
rect =3D [(0.2/fig_width), (0.5/fig_height),
(p_length/fig_width), (s_length/fig_height)]
=20
meter =3D H_Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
meter.set_axis_off()
fig.add_axes(meter)
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_value, 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] =3D=3D raw_limits[1] ):
raise ValueError('identical_limits_exception: %s' % =
raw_limits)
if( raw_limits[1] > raw_limits[0] ):
self.graph_positive =3D True
else: #Swap the limits around
self.graph_positive =3D False
raw_limits[0], raw_limits[1] =3D raw_limits[1] =3D =
raw_limits[0]
=20
if not( ((raw_limits[2]/raw_limits[3]) % 1.0) * raw_limits[3] =
=3D=3D 0 ): #There must be an integer number of minor ticks for each =
major tick
raise ValueError('bad_tick_spacing_exception')
if( raw_limits[2] <=3D 0 or raw_limits[3] <=3D 0 or =
raw_limits[2] < raw_limits[3] or raw_limits[3] > =
abs(raw_limits[1]-raw_limits[0]) ):
raise ValueError('bad_limits_exception:%s' % raw_limits)
for zone in raw_zones:
if( zone[0] > zone[1] ): #Swap the zones so zone[1] > =
zone[0]
zone[0], zone[1] =3D zone[1] =3D zone[0]
if( zone[1] < raw_limits[0] or zone[0] > raw_limits[1] =
):
raise ValueError('bad_zone_exception'%zone)
if( zone[0] < raw_limits[0] ):
zone[0] =3D raw_limits[0]
if( zone[1] > raw_limits[1] ):
zone[1] =3D raw_limits[1]
=20
#Adjust the scaling
self.scaled_limits =3D []
for limit in raw_limits:
self.scaled_limits.append( limit * p_length / =
(raw_limits[1]-raw_limits[0]))
=20
=20
#Stuff all of the variables into self.
self.vertical =3D vertical
self.raw_value =3D raw_value
self.raw_limits =3D raw_limits
self.raw_zones =3D raw_zones
self.attribute_name =3D attribute_name
self.field_names =3D field_names
self.file_name =3D file_name
self.resolution =3D resolution
self.p_length =3D p_length
self.s_length =3D s_length
=20
#Draw the meter
self.graph_center =3D =
((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_ticks()
self.draw_needle()
if( self.vertical ):
self.text( self.s_length/2, self.scaled_limits[0]-0.1, =
self.attribute_name, size=3D12, va=3D'top', ha=3D'center')
else:
self.text( self.graph_center, self.s_length+0.25, =
self.attribute_name, size=3D12, va=3D'bottom', ha=3D'center')
=20
def draw_bar( self, zone, border):
if( border ):
start =3D self.scaled_limits[0]
end =3D self.scaled_limits[1]
else:
start =3D (zone[0] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0]))
end =3D (zone[1] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0]))
colour =3D zone[2]
=20
if( not self.graph_positive ):
start =3D -start
end =3D -end
=20
s_vect =3D [ 0.0, 0.0, self.s_length, self.s_length ]
p_vect =3D [ start, end, end, start ]
=20
if( border ):
#Close the loop
p_vect.append(start)
s_vect.append(0.0)
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
p =3D self.plot(p_vect, s_vect, 'b-', color=3D'black', =
linewidth=3D1.5)
else:
if( self.vertical ):
p =3D self.fill(s_vect, p_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
else:
p =3D self.fill(p_vect, s_vect, colour, linewidth=3D0.0, =
alpha=3D0.4)
def draw_needle( self ): =20
if( self.raw_value =3D=3D None ):
if( self.vertical ):
self.text( (self.s_length + 0.05), self.graph_center, =
"N/A", size=3D10, va=3D'center', ha=3D'left')
else:
self.text( self.graph_center, (self.s_length + 0.05), =
"N/A", size=3D10, va=3D'bottom', ha=3D'center')
else:
#Clamp the value to the limits
value =3D self.raw_value * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
if( self.raw_value < self.raw_limits[0] ):
value =3D self.raw_limits[0] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
if( self.raw_value > self.raw_limits[1] ):
value =3D self.raw_limits[1] * self.p_length / =
(self.raw_limits[1]-self.raw_limits[0])
=20
if( self.vertical ):
self.text( (self.s_length + 0.05), value, "%.2f" % =
self.raw_value, size=3D10, va=3D'center', ha=3D'left')=20
else:
self.text( value, (self.s_length + 0.05), "%.2f" % =
self.raw_value, size=3D10, va=3D'bottom', ha=3D'center')=20
=20
if( not self.graph_positive ):
value =3D -value
s_vect =3D [ self.s_length/2, self.s_length, self.s_length ]
p_vect =3D [ value + 0.00, value - 0.05, value + 0.05 ]
=20
if( self.vertical ):
self.fill(s_vect, p_vect, 'black')
else:
self.fill(p_vect, s_vect, 'black')
=20
=20
def draw_ticks( self ):
if( self.graph_positive ):
offset =3D self.scaled_limits[0]
else:
offset =3D self.scaled_limits[1]
i =3D 0
j =3D self.raw_limits[0]
while( i*self.scaled_limits[3] + self.scaled_limits[0] <=3D =
self.scaled_limits[1] ):
if( i % (self.scaled_limits[2]/self.scaled_limits[3]) =3D=3D =
0):
tick_length =3D self.s_length
if( self.vertical ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( -0.05, offset, "%.2f" % j, size=3D10, =
va=3D'center', ha=3D'right')=20
else:
self.text( -0.05, offset, "%d" % int(j), =
size=3D10, va=3D'center', ha=3D'right')
else: =20
tick_length =3D self.s_length
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( offset, -0.05, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( offset, -0.05, "%d" % int(j), =
size=3D10, va=3D'top', ha=3D'center')=20
j +=3D self.raw_limits[2]
else:
tick_length =3D self.s_length * 0.2
=20
s_vect =3D [ 0.0, tick_length ]
p_vect =3D [ offset, offset ]
=20
if( self.vertical ):
p =3D self.plot(s_vect, p_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
else:
p =3D self.plot(p_vect, s_vect, 'b-', linewidth=3D1, =
color=3D'black', alpha=3D0.2)
i +=3D 1
if( self.graph_positive ):
offset +=3D self.scaled_limits[3]
else:
offset -=3D self.scaled_limits[3]
=20
if( i % (self.scaled_limits[2]/self.scaled_limits[3]) =3D=3D 0):
if( self.vertical ):
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( -0.01, offset, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( -0.01, offset, "%d" % int(j), size=3D10, =
va=3D'top', ha=3D'center')=20
else:
if( type(self.raw_limits[2]) is types.FloatType ):
self.text( offset, -0.1, "%.2f" % j, size=3D10, =
va=3D'top', ha=3D'center')=20
else:
self.text( offset, -0.1, "%d" % int(j), size=3D10, =
va=3D'top', ha=3D'center')=20
=20
def make_widget( vertical, raw_value, raw_limits, raw_zones, =
attribute_name, field_names, file_name, resolution=3D72 ):
from pylab import figure, show, savefig
=20
p_length =3D 2.0 # Length of the Primary axis
s_length =3D 0.3 # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 0.6
fig_width =3D s_length + 1.0
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.5/fig_width), (0.4/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(vertical, raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,=20
p_length, s_length,
fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[]
)
else:
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.2/fig_width), (0.5/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(vertical, raw_value,=20
raw_limits, raw_zones,=20
attribute_name, field_names,=20
file_name, resolution,
p_length, s_length,
fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure( file_name,dpi=3Dresolution ) =20
=20
=20
#make_widget( False, -3.0, [-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'], 'meter.png', 100)
=20
''' =20
if __name__=3D=3D'__main__':
from pylab import figure, show, savefig
=20
vertical =3D True =20
=20
raw_value =3D None
raw_limits =3D [-10.0,10.0,5,1]
raw_zones =3D [[-10.0,0.0,'r'],[0.0,5.0,'y'],[5.0,10.0,'g']]
attribute_name =3D "Rx MOS (24h)"
=20
p_length =3D 2.0 # Length of the Primary axis
s_length =3D 0.3 # Length of the Secondary axis
=20
if( vertical ):=20
fig_height =3D p_length + 0.6
fig_width =3D s_length + 1.0
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.5/fig_width), (0.4/fig_height), =
(s_length/fig_width), (p_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.2, s_length+0.1 ),
ylim=3D( -0.1, p_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
else:
fig_height =3D s_length + 1.0
fig_width =3D p_length + 0.4
fig =3D figure( figsize=3D(fig_width, fig_height) )
rect =3D [(0.2/fig_width), (0.5/fig_height), =
(p_length/fig_width), (s_length/fig_height)]
meter =3D Meter(fig, rect,
xlim=3D( -0.1, p_length+0.1 ),
ylim=3D( -0.4, s_length+0.1 ),
xticks=3D[],
yticks=3D[],
)
=20
meter.set_axis_off()
fig.add_axes(meter)
# show()
fig.canvas.print_figure('meter',dpi=3D72)
'''
|
|
From: John H. <jdh...@ac...> - 2005-07-26 14:16:39
|
>>>>> "Steve" == Steve Chaplin <ste...@ya...> writes:
Steve> For the people that like to maximise the size of their
Steve> graphs I've updated the key-press-event so that pressing
Steve> 'g' toggles fullscreen mode. (It requires GTK+ 2.2 or
Steve> higher and a window manager that honours window fullscreen
Steve> requests).
Very nice! But I think you mean 'f', right?
JDH
|
|
From: Steve C. <ste...@ya...> - 2005-07-26 08:18:05
|
For the people that like to maximise the size of their graphs I've updated the key-press-event so that pressing 'g' toggles fullscreen mode. (It requires GTK+ 2.2 or higher and a window manager that honours window fullscreen requests). Steve Send instant messages to your online friends http://au.messenger.yahoo.com |
|
From: John H. <jdh...@ac...> - 2005-07-25 14:29:23
|
>>>>> "Ted" == Ted Drain <ted...@jp...> writes:
Ted> The legend() docs state: Make a legend with existing lines
>>>> legend()
Ted> legend by itself will try and build a legend using the
Ted> label property of the lines/patches/collections. You can set
Ted> the label of a line by doing plot(x, y, label='my data') or
Ted> line.set_label('my data'). If label is set to '_nolegend_',
Ted> the item will not be shown in legend.
The docs say this only in reference to autolegend capability (eg when
you call legend with no arguments). And this does work
import pylab as p
x = p.arange( 0,3, .1 )
p.plot( x, p.cos(x), label='cos(x)' )
p.plot( x, p.sin(x), label='sin(x)')
p.plot( x, 2*p.sin(x), label='_nolegend_' )
p.legend()
p.show()
It isn't really required in your use case, because you can simply pass
the lines and labels you want in the legend
import pylab as p
x = p.arange( 0,3, .1 )
l0, = p.plot( x, p.cos(x))
l1, = p.plot( x, p.sin(x))
l2, = p.plot( x, 2*p.sin(x))
p.legend((l0, l1), ('cos(x)', 'sin(x)') )
p.show()
It would not be too much work to support the semi-auto legending of
your example
p.legend( ( "cos(x)", "_nolegend_", "2*sin(x)" ) )
if you think this is sufficiently useful.
JDH
|
|
From: John H. <jdh...@ac...> - 2005-07-25 14:17:01
|
>>>>> "Steve" == Steve Chaplin <ste...@ya...> writes:
Steve> Also, I see the frontend file lines.py has: import
Steve> matplotlib.agg
matplotlib does not require the agg backend, but it does require a
minimal bit of agg functionality. Specifically, agg::path_storage us
the cross-backend path storage class, which you use in backend_cairo
in the draw_markers function. As you probably remember, I started out
with a simple list of tuples to represent a path, but eventually
decided we would be better off with a full blown, bug vetted
implementation rather than rolling our own. agg's seemed a natural
choice because the code is already in the mpl code base, and it has
the additional benefit that backend_agg can use it with no overhead.
So backend matplotlib.backends._backend_agg and matplotlib.agg are
different beasts. The first is pycxx hand written code to implement
the Renderer and GC classes; the latter is a SWIG wrapper of agg. I
would like to do away with the former and replace all of it's
functionality with the latter (I started experimenting with this in
backend_agg2). The advantage of this is that agg users could also
draw directly onto the canvas using agg primitives and would not be
limited by the mpl drawing model.
This is a long winded way of saying that I have polluted the agg
module's minimal set of cross-backend agg functionality with some
graphics capability. I think the solution is to factor matplotlib.agg
this into two modules: one lightweight which has the rendering
independent computational geometry stuff which can be used across
backends, and one which has the rendering stuff . mpl has reinvented
(for the 40th time) many of the primitives that every graphics library
needs (color storage, path storage, affine transformations, etc...).
In the grand refactoring that I've wanted to do for many moons but
haven't found the time, I've envisioned replacing a lot of this custom
stuff with agg's. The code in matplotlib.agg layed the groundwork for
this, but as I say I got a little carried away and included other
antigrain stuff too.
How about two modules, the first required ("basics") that has
rectangles, path_storage, affine transformations, etc, and another
optional ("agg" or "antigrain") which has the rendering buffers,
renderers, strokes and so on, thus keeping the cross-backend required
component as light as possible. The only objection I can think of is
that is makes C++ a core requirement for mpl, but it already is for
the _transforms and ft2font modules.
Does this sound reasonable to you? Do you have any objection to
reusing a minimal set of agg across backends?
JDH
|
|
From: Abraham S. <ab...@cn...> - 2005-07-25 04:27:47
|
Hi, just thought I'd check if this was a (fairly minor) bug. In the psd
function there is:
if NFFT % 2:
raise ValueError, 'NFFT must be a power of 2'
But that will only check if NFFT is an even number or not. Should this
instead be:
if not ispower2(NFFT):
raise ValueError, 'NFFT must be a power of 2'
?
Abe
|
|
From: Steve C. <ste...@ya...> - 2005-07-24 13:46:22
|
I always thought of matplotlib as providing a graphics library neutral
frontend, which can be coupled with a choice of many backends.
However, if I choose to edit setup.py and change
BUILD_AGG = 1
to
BUILD_AGG = 0
(and BUILD_IMAGE = 0 too)
after 'python setup.py build'
I still see the message "building 'matplotlib._agg' extension"
and notice that agg.py and _agg.so still get installed.
Also, I see the frontend file lines.py has:
import matplotlib.agg
So even if someone wishes to use just the ps, svg, cairo or gtk backends,
they must compile, install, and import agg even though they did not wish
to use it.
Steve
Send instant messages to your online friends http://au.messenger.yahoo.com
|