Source code for sas.sasgui.guiframe.local_perspectives.plotting.Arc
"""
Arc slicer for 2D data
"""
import math
from BaseInteractor import _BaseInteractor
from sas.sasgui.guiframe.events import SlicerParameterEvent
[docs]class ArcInteractor(_BaseInteractor):
"""
Select an annulus through a 2D plot
"""
def __init__(self, base, axes, color='black', zorder=5, r=1.0,
theta1=math.pi / 8, theta2=math.pi / 4):
_BaseInteractor.__init__(self, base, axes, color=color)
self.markers = []
self.axes = axes
self._mouse_x = r
self._mouse_y = 0
self._save_x = r
self._save_y = 0
self.scale = 10.0
self.theta1 = theta1
self.theta2 = theta2
self.radius = r
[self.arc] = self.axes.plot([], [], linestyle='-', marker='', color=self.color)
self.npts = 20
self.has_move = False
self.connect_markers([self.arc])
self.update()
[docs] def set_layer(self, n):
"""
Allow adding plot to the same panel
:param n: the number of layer
"""
self.layernum = n
self.update()
[docs] def clear(self):
"""
Clear this slicer and its markers
"""
self.clear_markers()
try:
for item in self.markers:
item.remove()
self.arc.remove()
except:
# Old version of matplotlib
for item in range(len(self.axes.lines)):
del self.axes.lines[0]
[docs] def get_radius(self):
"""
Return arc radius
"""
radius = math.sqrt(math.pow(self._mouse_x, 2) + \
math.pow(self._mouse_y, 2))
return radius
[docs] def update(self, theta1=None, theta2=None, nbins=None, r=None):
"""
Update the plotted arc
:param theta1: starting angle of the arc
:param theta2: ending angle of the arc
:param nbins: number of points along the arc
:param r: radius of the arc
"""
# Plot inner circle
x = []
y = []
if theta1 is not None:
self.theta1 = theta1
if theta2 is not None:
self.theta2 = theta2
while self.theta2 < self.theta1:
self.theta2 += (2 * math.pi)
while self.theta2 >= (self.theta1 + 2 * math.pi):
self.theta2 -= (2 * math.pi)
npts = int((self.theta2 - self.theta1) / (math.pi / 120))
if r is None:
self.radius = math.sqrt(math.pow(self._mouse_x, 2) + \
math.pow(self._mouse_y, 2))
else:
self.radius = r
for i in range(self.npts):
phi = (self.theta2 - self.theta1) / (self.npts - 1) * i + self.theta1
xval = 1.0 * self.radius * math.cos(phi)
yval = 1.0 * self.radius * math.sin(phi)
x.append(xval)
y.append(yval)
# self.marker.set(xdata=[self._mouse_x],ydata=[0])
self.arc.set_data(x, y)
[docs] def save(self, ev):
"""
Remember the roughness for this layer and the next so that we
can restore on Esc.
"""
self._save_x = self._mouse_x
self._save_y = self._mouse_y
# self._save_x = ev.xdata
# self._save_y = ev.ydata
self.base.freeze_axes()
[docs] def moveend(self, ev):
"""
After a dragging motion reset the flag self.has_move to False
:param ev: event
"""
self.has_move = False
event = SlicerParameterEvent()
event.type = self.__class__.__name__
event.params = self.get_params()
self.base.moveend(ev)
[docs] def restore(self):
"""
Restore the roughness for this layer.
"""
self._mouse_x = self._save_x
self._mouse_y = self._save_y
[docs] def move(self, x, y, ev):
"""
Process move to a new position, making sure that the move is allowed.
"""
# print "ring move x, y", x,y
self._mouse_x = x
self._mouse_y = y
self.has_move = True
self.base.base.update()
[docs] def set_cursor(self, radius, phi_min, phi_max, nbins):
"""
"""
self.theta1 = phi_min
self.theta2 = phi_max
self.update(nbins=nbins, r=radius)
[docs] def get_params(self):
"""
"""
params = {}
params["radius"] = self.radius
params["theta1"] = self.theta1
params["theta2"] = self.theta2
return params
[docs] def set_params(self, params):
"""
"""
x = params["radius"]
phi_max = self.theta2
nbins = self.npts
self.set_cursor(x, self._mouse_y, phi_max, nbins)