1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
|
## Automatically adapted for scipy Oct 31, 2005 by
# Copyright (c) 1996, 1997, The Regents of the University of California.
# All rights reserved. See Legal.htm for full text and disclaimer.
from graph import *
from graftypes import *
class Graph2d ( Graph ) :
"""
g = Graph2d ( <curve list>, ...keyword arguments...) will create
a two-dimensional graphics object consisting of several curves
plus a global environment for the object. It will accept one or
a list of Plotter objects or plotter_identifiers, or will try
to complete a generic connection of its own if asked to plot
without such a plotter specification.
<curve list> is one or a sequence of Curve, Lines, QuadMesh,
CellArray, or PolyMap objects.
The keyword arguments for Graph2d are:
plotter = <Plotter object> or a sequence of <Plotter object>s
if you have a plotter object or a sequence of them that
you want the curve to use when plotting itself. I
recommend against this; a curve can create its own
plotter if you don't give it one.
filename = <string> or a sequence of <string>s if you want to
connect to Narcisse with the named file(s). (The default
is " ".) Only one of the keywords 'plotter' or 'filename'
is allowed, and both are optional.
NOTE: the possibility of a sequence of file names or
plotters allows one to display Narcisse graphs on one's
own machine as well as one or more remote machines.
In Gist, the filename argument is the same as the
display argument (below).
display = <string> or a sequence of <string>s if you want to
display on the named hosts. The form of <string> is
the usual "hostname:server.screen". The purpose of
this argument is to allow you to continue without
exiting python if you have to open a Gist window
without the DISPLAY environment variable having been
set, or if you want to open Gist windows on more
than one host.
style = one of "vg.gs", "boxed.gs", "vgbox.gs", "nobox.gs",
"work.gs". For Gist only, and only if a plotter has
not been specified, each plotter opened will be opened
with the specified style. The default is "work.gs".
grid_type = <string> where "none" means no axis grid;
"axes" means a pair of axes with tick marks;
"wide" means a widely spaced 2d grid; and
"full" means a closely spaced 2d grid.
label_type = "end" (to label the curve at its end)
"box" (to put the labels in a box)
titles = <value> where <value> is a string or a sequence
of up to four strings, giving the titles in the
order bottom, top, left, right.
title_colors = <value> where value is an integer or string
or a sequence of up to four integers or strings giving
the colors of the titles.
grid_type = <string> where "none" means no axis grid;
"axes" means a pair of axes with tick marks;
"wide" means a widely spaced 2d grid; and
"full" means a closely spaced 2d grid.
axis_labels = <value> where <value> is a string or
sequence of up to three strings representing
the labels of the x axis, the y axis, and the
right y axis.
x_axis_label, y_axis_label, and yr_axis_label may be used
to label individual axes.
axis_limits = <value> where <value> is a pair [xmin, xmax] or
a sequence of up to three pairs, where the second
would be the y limits, and the third the yr limits.
x_axis_limits, y_axis_limits, and yr_axis_limits may be used
to specify limits on individual axes.
axis_scales = "linlin", "linlog", "loglin", or "loglog"
or, if all three axes are to be specified, a
triple of the values "lin" and "log".
x_axis_scale, y_axis_scale, and yr_axis_scale may be used
to specify individual axis scales.
text = <value> where value is one or a sequence of strings
representing texts to be placed on the plot.
text_color = <value> where <value> is one or a sequence
of color numbers or names giving colors for the
texts.
text_size = <value> where <value> is one or a sequence of
integers giving (roughly) the number of characters
in a line on the graph.
text_pos = <value> where <value> is a pair or a sequence or
reals between 0. and 1.0 giving the relative
position of the lower left corner of a text
in the graphics window.
color_card = <value> specifies which color card you wish
to use, e. g., "rainbowhls" (the default), "random",
etc. Note that for curves, color_card is a Graph2d
keyword, since it is not possible to specify
different color cards on the same 2d graph,
whereas linked 3d and 4d graphs can have
different color cards; therefore for these,
it is a Surface keyword.
sync = 0 or 1 (1 to synchronize before sending a plot)
defaults to 1, otherwise plots may get garbled.
color_bar = 0 or 1 (1 enables plotting of a color bar on
any graphs for which it is meaningful (colored contour
plots, filled contour plots, cell arrays, filled
meshes and polygons).
color_bar_pos (ignored unless a color bar is actually plotted)
is a 2d array [ [xmin, ymin], [xmax, ymax]] specifying
where (in window coordinates) the diagonally opposite
corners of the color bar are to be placed.
"""
_axes = ["x", "y", "yr"]
_NotA2dObject = "NotA2dObject"
# The following are actually used in Graph
_limits_keywords = ["x_axis_limits", "y_axis_limits", "yr_axis_limits"]
_scale_keywords = ["x_axis_scale", "y_axis_scale", "yr_axis_scale"]
_label_keywords = ["x_axis_label", "y_axis_label", "yr_axis_label"]
_no_of_axes = 3
def type (self) :
return Graph2dType
def __init__ ( self , curve_list , *kwds , ** keywords ) :
if len ( kwds ) == 1 :
keywords = kwds[0]
if is_scalar ( curve_list ) :
self.check_curve (curve_list)
self._c = [curve_list]
else :
for i in range ( len ( curve_list ) ) :
self.check_curve (curve_list [i])
self._c = curve_list
self._c_ln = len (self._c)
if keywords.has_key ("label") :
self._label = keywords ["label"]
else :
self._label = " "
if keywords.has_key ("label_type") :
self._label_type = keywords ["label_type"]
else :
self._label_type = " "
if keywords.has_key ( "color_card" ) :
self._color_card = keywords ["color_card"]
else :
self._color_card = "default"
# Everything else is Graph generic:
self._axis_limits = [[0., 0.], [0., 0.], [0., 0.]]
self._axis_scales = ["lin", "lin", "lin"]
self._axis_labels = ["X axis", "Y axis", "YR axis"]
Graph.__init__ ( self , keywords )
if keywords.has_key ("grid_type") :
self._grid_type = keywords ["grid_type"]
else :
self._grid_type = "axes"
if keywords.has_key ("style") :
self._style = keywords ["style"]
else :
self._style = "work.gs"
def new ( self , curve_list , ** keywords ) :
"""new ( curves, <keyword arguments> ) cleans out a Graph2d
and reinitializes it. This has the same argument list as
Graph2d. Do not change the plotter list or filename list (to
avoid the tedious on-and-off flickering of windows) unless
this is actually requested.
"""
del self._c
pl = self._plotter_list
fl = self._filename_list
self._plotter_list = []
self._filename_list = []
self.__init__ ( curve_list , keywords )
if self._plotter_list == [] :
self._plotter_list = pl
self._filename_list = fl
def set ( self , ** keywords ) :
""" set (...keyword arguments...) allows you to set individual
Graph2d characteristics. No error checking is done.
It will only change the plotter if specifically asked to do so.
"""
self._filename = ""
self._display = ""
self._plotter = None
for k in keywords.keys ():
setattr (self, "_" + k, keywords [k])
if is_scalar (self._filename) and self._filename != "" :
self._filename_list = [self._filename]
self._plotter_list = [-1]
elif is_scalar (self._display) and self._display != "" :
self._filename_list = [self._display]
self._plotter_list = [-1]
elif self._filename != "" :
self._filename_list = self._filename
self._plotter_list = [-1] * len (self._filename_list)
elif self._display != "" :
self._filename_list = self._display
self._plotter_list = [-1] * len (self._filename_list)
elif self._plotter is not None :
if is_scalar (self._plotter) :
self._plotter_list = [self._plotter]
self._filename_list = [" "]
else :
self._plotter_list = self._plotter
self._filename_list = [" "] * len (self._plotter_list)
def check_curve (self, crv) :
"""check_curve (crv) raises an exception if crv is not a legal
2d object.
"""
try :
dum = crv.type ()
except:
raise self._NotA2dObject , "Illegal object sent to Graph2d."
if crv.type () != CurveType and \
crv.type () != LinesType and \
crv.type () != PolyMapType and \
crv.type () != CellArrayType and \
crv.type () != QuadMeshType and \
crv.type () != Animation2dType :
raise self._NotA2dObject , "Illegal object (type " + \
`crv.type ()` + ") sent to Graph2d."
return
def add ( self , curve ) :
""" add ( curve ) adds a curve with its characteristics to the
existing plot. Curves are numbered in the order that they are
added, beginning with 1.
"""
self.check_curve (curve)
self._c.append ( curve )
self._c_ln = len (self._c)
def delete ( self , n ) :
"""delete ( n ) n integer: deletes the nth curve from the Graph. Note
that curves are numbered beginning with 1.
n a curve (etc.) object: deletes that object, if it is present.
"""
DeleteError = "DeleteError"
if type (n) == IntType and 1 <= n <= self._c_ln :
self._c [n-1:n] = []
self._c_ln = len (self._c)
elif type (n) == IntType :
raise DeleteError , "There is no curve numbered " + `n` + \
" in the current graph, which has only " + `self._c_ln` + \
" curves."
else :
for i in range (self._c_ln) :
if n == self._c [i] :
del self._c [i]
self._c_ln = self._c_ln - 1
return
def replace ( self , n , curve ) :
"""replace ( n , curve ) n integer : replaces the nth curve in the Graph
with the specified curve. Note that curves are numbered beginning with 1.
n a curve (etc.) object: replaces that object, if it is present.
"""
self.check_curve (curve)
ReplaceError = "ReplaceError"
if IntType == type (n) and 1 <= n <= self._c_ln :
self._c [n-1] = curve
elif IntType == type (n) :
raise ReplaceError , "There is no curve numbered " + `n` + \
" in the current graph, which has only " + `self._c_ln` + \
" curves."
else :
for i in range (self._c_ln) :
if n == self._c [i] :
self._c [i] = n
return
else :
raise ReplaceError , "Attempt to remove an object not on the list."
_CurveChangeError = "CurveChangeError"
def change_curves (self, curve_or_list) :
""" change_curves ( <curve or curve list> ) is designed to replace
the entire curve list.
"""
if is_scalar ( curve_or_list ) :
self.check_curve (curve_or_list)
self._c = [curve_or_list]
else :
for i in range ( len ( curve_or_list ) ) :
self.check_curve (curve_or_list [i])
self._c = curve_or_list
self._c_ln = len (self._c)
return
def change_plot ( self , ** keywords ) :
"""change_plot ( <keyword arguments> ) is used to change any Graph2d
characteristics except the curves being graphed. Use the add,
delete, and/or replace commands to do that. change_plot will
draw the graph without sending object surface coordinates, unless
keyword send is 1. Generally, change_plot should be used when
the graph needs to be recomputed, and quick_plot when it does not.
change_plot does no error checking and does not conver user-friendly
names of colors and such into numbers.
change_curves ( <curve or curve list> ) may be used to replace
thr rntire curve list.
"""
for k in keywords.keys ():
if k == "curve" :
raise self._CurveChangeError, \
"Use add, delete, or replace to change curves in a graph."
setattr (self, "_" + k, keywords [k])
if "send" in keywords.keys ():
send = keywords ["send"]
self._send_coordinates = send
self.plot ( )
self._send_coordinates = 1
def quick_plot ( self , ** keywords ) :
"""quick_plot ( <keyword arguments> ) is used to change some Graph2d
characteristics which do not demand that the graph be recomputed.
You can change the characteristics of a curve in the graph by
specifying its number (curve = n) and any combination of the
traits type, color, and label. Or you can change such overall
graph characteristics as label_type, titles, title_colors,
text, text_color, text_size, text_pos, color_card, grid_type,
sync, and axis_labels. The changes will be effected and the graph
redrawn.
Things that you cannot change include axis limits and scales,
and the coordinates of a curve. Use change_plot if axis limits
and scales are among the things you want to change, and use add,
delete, or replace followed by a call to plot, if you wish to
change a curve.
quick_plot will tell you if you try to change something illegal.
"""
ChangeError = "ChangeError"
PlottersNotStarted = "PlottersNotStarted"
if not self._plotters_started :
raise PlottersNotStarted , \
"quick_plot requires that all plotters have already been started."
if keywords.has_key ( "curve" ) :
n = keywords ["curve"]
del keywords ["curve"]
self.type_change = 0
self.color_change = 0
self.label_change = 0
if 1 <= n <= self._c_ln :
if keywords.has_key ("type") :
self._c[n - 1].line_type = keywords ["type"]
del keywords ["type"]
self.type_change = 1
if keywords.has_key ("color") :
self._c[n - 1].color = keywords ["color"]
del keywords ["color"]
self.color_change = 1
if keywords.has_key ("label") :
self._c[n - 1].label = keywords ["label"]
self.label_change = 1
del keywords ["label"]
else :
raise ChangeError , "There is no curve numbered " + `n` + \
" in the current graph, which has only " + `self._c_ln` + \
" curves."
if keywords.has_key ("label_type") :
self._label_type = keywords ["label_type"]
del keywords ["label_type"]
if keywords.has_key ( "color_card" ) :
self._color_card = keywords ["color_card"]
del keywords ["color_card"]
if keywords.has_key ("grid_type") :
self._grid_type = keywords ["grid_type"]
del keywords ["grid_type"]
Graph.change ( self , keywords ) # Change generic traits
if len (keywords.keys ()) > 0 :
print "Note: quick_plot will ignore keywords" , keywords.keys () , "."
print "-- Use change_plot instead."
for ipl in range (len (self._plotter_list)) :
pl = self._plotter_list [ipl]
try :
dum = Nar
except :
self.plot (pl)
else :
if self._graphics_list [ipl] == Nar :
pl.quick_plot (self)
else :
self.plot (pl)
def plot ( self , plotter = None) :
"""plot ( ) plots a 2d graph object. If the user has not by
now specified plotter(s) or filename(s) then a generic plotter
object will be created, if it is possible to find a local
Graphics routine.
"""
self._init_plotter ( )
if plotter is not None :
plotter.plot2d (self)
return
for ipl in range (len (self._plotter_list)) :
pl = self._plotter_list [ipl]
pl.plot2d (self)
|