-
-class DrawCmd:
- """Represent a "draw" command, i.e. the one given in call to
- PlotCanvas.Draw(). The axis specs are not saved to preserve
- backward compatibility: they could be specified before the
- first Draw() command."""
- def __init__(self, graphics, xAxis, yAxis, xSpec, ySpec, xTicks, yTicks):
- """Same args as PlotCanvas.Draw(), plus axis specs."""
- self.graphics = graphics
- self.xTickGen = xTicks
- self.yTickGen = yTicks
- self.xAxisInit, self.yAxisInit = xAxis, yAxis
-
- self.xAxis = None
- self.yAxis = None
- self.changeAxisX(xAxis, xSpec)
- self.changeAxisY(yAxis, ySpec)
- assert self.xAxis is not None
- assert self.yAxis is not None
-
- def isEmpty(self):
- """Return true if either axis has 0 size."""
- if self.xAxis[0] == self.xAxis[1]:
- return True
- if self.yAxis[0] == self.yAxis[1]:
- return True
-
- return False
-
- def resetAxes(self, xSpec, ySpec):
- """Reset the axes to what they were initially, using axes specs given."""
- self.changeAxisX(self.xAxisInit, xSpec)
- self.changeAxisY(self.yAxisInit, ySpec)
-
- def getBoundingBox(self):
- """Returns p1, p2 (two pairs)"""
- p1 = _Numeric.array((self.xAxis[0], self.yAxis[0]))
- p2 = _Numeric.array((self.xAxis[1], self.yAxis[1]))
- return p1, p2
-
- def getClosestPoints(self, pntXY, pointScaled=True):
- ll = []
- for curveNum,obj in enumerate(self.graphics):
- #check there are points in the curve
- if len(obj.points) == 0:
- continue #go to next obj
- #[curveNumber, legend, index of closest point, pointXY, scaledXY, distance]
- cn = [curveNum, obj.getLegend()]+\
- obj.getClosestPoint( pntXY, pointScaled)
- ll.append(cn)
- return ll
-
- def scrollAxisX(self, units, xSpec):
- """Scroll y axis by units, using ySpec for axis spec."""
- self.changeAxisX((self.xAxis[0]+units, self.xAxis[1]+units), xSpec)
-
- def scrollAxisY(self, units, ySpec):
- """Scroll y axis by units, using ySpec for axis spec."""
- self.changeAxisY((self.yAxis[0]+units, self.yAxis[1]+units), ySpec)
-
- def changeAxisX(self, xAxis=None, xSpec=None):
- """Change the x axis to new given, or if None use ySpec to get it. """
- assert type(xAxis) in [type(None),tuple]
- if xAxis is None:
- p1, p2 = self.graphics.boundingBox() #min, max points of graphics
- self.xAxis = self._axisInterval(xSpec, p1[0], p2[0]) #in user units
- else:
- self.xAxis = xAxis
-
- def changeAxisY(self, yAxis=None, ySpec=None):
- """Change the y axis to new given, or if None use ySpec to get it. """
- assert type(yAxis) in [type(None),tuple]
- if yAxis is None:
- p1, p2 = self.graphics.boundingBox() #min, max points of graphics
- self.yAxis = self._axisInterval(ySpec, p1[1], p2[1])
- else:
- self.yAxis = yAxis
-
- def zoom(self, center, ratio):
- """Zoom to center and ratio."""
- x,y = Center
- w = (self.xAxis[1] - self.xAxis[0]) * Ratio[0]
- h = (self.yAxis[1] - self.yAxis[0]) * Ratio[1]
- self.xAxis = ( x - w/2, x + w/2 )
- self.yAxis = ( y - h/2, y + h/2 )
-
- def getXMaxRange(self):
- p1, p2 = self.graphics.boundingBox() #min, max points of graphics
- return self._axisInterval(self._xSpec, p1[0], p2[0]) #in user units
-
- def getYMaxRange(self):
- p1, p2 = self.graphics.boundingBox() #min, max points of graphics
- return self._axisInterval(self._ySpec, p1[1], p2[1]) #in user units
-
- def getTicksX(self):
- """Get the ticks along y axis. Actually pairs of (t, str)."""
- xticks = self._ticks(self.xAxis[0], self.xAxis[1], self.xTickGen)
- if xticks == []: # try without the generator
- xticks = self._ticks(self.xAxis[0], self.xAxis[1])
- return xticks
-
- def getTicksY(self):
- """Get the ticks along y axis. Actually pairs of (t, str)."""
- yticks = self._ticks(self.yAxis[0], self.yAxis[1], self.yTickGen)
- if yticks == []: # try without the generator
- yticks = self._ticks(self.yAxis[0], self.yAxis[1])
- return yticks
-
- def _axisInterval(self, spec, lower, upper):
- """Returns sensible axis range for given spec."""
- if spec == 'none' or spec == 'min':
- if lower == upper:
- return lower-0.5, upper+0.5
- else:
- return lower, upper
- elif spec == 'auto':
- range = upper-lower
- if range == 0.:
- return lower-0.5, upper+0.5
- log = _Numeric.log10(range)
- power = _Numeric.floor(log)
- fraction = log-power
- if fraction <= 0.05:
- power = power-1
- grid = 10.**power
- lower = lower - lower % grid
- mod = upper % grid
- if mod != 0:
- upper = upper - mod + grid
- return lower, upper
- elif type(spec) == type(()):
- lower, upper = spec
- if lower <= upper:
- return lower, upper
- else:
- return upper, lower
- else:
- raise ValueError, str(spec) + ': illegal axis specification'
-
- def _ticks(self, lower, upper, generator=None):
- """Get ticks between lower and upper, using generator if given. """