6
6
from __future__ import division
9
from cbook import is_string_like, enumerate, strip_math, Stack
9
from cbook import is_string_like, enumerate, strip_math, Stack, CallbackRegistry
10
10
from colors import colorConverter
11
11
from numerix import array, sqrt, pi, log, asarray, ones, zeros, Float, Float32
12
12
from numerix import arange, compress, take, isnan, any
37
def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2, rotation):
37
def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2,
39
40
Draw an arc using GraphicsContext instance gcEdge, centered at x,y,
40
41
with width and height and angles from 0.0 to 360.0
480
483
self._antialiased = gc._antialiased
481
484
self._capstyle = gc._capstyle
482
485
self._cliprect = gc._cliprect
486
self._clippath = gc._clippath
483
487
self._dashes = gc._dashes
484
488
self._joinstyle = gc._joinstyle
485
489
self._linestyle = gc._linestyle
778
795
self.button = button
798
class PickEvent(Event):
800
a pick event, fired when the user picks a location on the canvas
801
sufficiently close to an artist.
803
Attrs: all the Event attrs plus
804
mouseevent : the MouseEvent that generated the pick
805
artist : the artist picked
807
extra class dependent attrs -- eg a Line2D pick may define
808
different extra attributes than a PatchCollection pick event
810
def __init__(self, name, canvas, mouseevent, artist, guiEvent=None, **kwargs):
811
Event.__init__(self, name, canvas, guiEvent)
812
self.mouseevent = mouseevent
814
self.__dict__.update(kwargs)
781
817
class KeyEvent(LocationEvent):
783
819
A key event (key press, key release).
813
849
figure - A Figure instance
817
855
'key_press_event',
818
856
'key_release_event',
819
857
'button_press_event',
820
858
'button_release_event',
821
859
'motion_notify_event',
824
864
def __init__(self, figure):
825
865
figure.set_canvas(self)
826
866
self.figure = figure
828
867
# a dictionary from event name to a dictionary that maps cid->func
868
self.callbacks = CallbackRegistry(self.events)
830
869
self.widgetlock = widgets.LockDraw()
831
870
self._button = None # the button pressed
832
871
self._key = None # the key pressed
848
887
def draw_event(self, renderer):
849
event = DrawEvent('draw_event', self, renderer)
850
for func in self.callbacks.get('draw_event', {}).values():
889
event = DrawEvent(s, self, renderer)
890
self.callbacks.process(s, event)
853
892
def resize_event(self):
854
event = ResizeEvent('resize_event', self)
855
for func in self.callbacks.get('resize_event', {}).values():
894
event = ResizeEvent(s, self)
895
self.callbacks.process(s, event)
858
897
def key_press_event(self, key, guiEvent=None):
860
event = KeyEvent('key_press_event', self, key, self._lastx, self._lasty, guiEvent=guiEvent)
861
for func in self.callbacks.get('key_press_event', {}).values():
899
s = 'key_press_event'
900
event = KeyEvent(s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
901
self.callbacks.process(s, event)
864
903
def key_release_event(self, key, guiEvent=None):
865
event = KeyEvent('key_release_event', self, key, self._lastx, self._lasty, guiEvent=guiEvent)
866
for func in self.callbacks.get('key_release_event', {}).values():
904
s = 'key_release_event'
905
event = KeyEvent(s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
906
self.callbacks.process(s, event)
909
def pick_event(self, mouseevent, artist, **kwargs):
911
This method will be called by artists who are picked and will
912
fire off PickEvent callbacks registered listeners
915
event = PickEvent(s, self, mouseevent, artist, **kwargs)
916
self.callbacks.process(s, event)
870
918
def button_press_event(self, x, y, button, guiEvent=None):
872
920
Backend derived classes should call this function on any mouse
874
922
button and key are as defined in MouseEvent
876
924
self._button = button
877
event = MouseEvent('button_press_event', self, x, y, button, self._key, guiEvent=guiEvent)
878
for func in self.callbacks.get('button_press_event', {}).values():
925
s = 'button_press_event'
926
mouseevent = MouseEvent(s, self, x, y, button, self._key, guiEvent=guiEvent)
927
self.callbacks.process(s, mouseevent)
930
if not self.widgetlock.locked():
931
self.figure.pick(mouseevent)
881
933
def button_release_event(self, x, y, button, guiEvent=None):
883
935
Backend derived classes should call this function on any mouse
884
936
button release. x,y are the canvas coords: 0,0 is lower, left.
885
937
button and key are as defined in MouseEvent
888
event = MouseEvent('button_release_event', self, x, y, button, self._key, guiEvent=guiEvent)
889
for func in self.callbacks.get('button_release_event', {}).values():
939
s = 'button_release_event'
940
event = MouseEvent(s, self, x, y, button, self._key, guiEvent=guiEvent)
941
self.callbacks.process(s, event)
891
942
self._button = None
893
944
def motion_notify_event(self, x, y, guiEvent=None):
897
948
button and key are as defined in MouseEvent
899
950
self._lastx, self._lasty = x, y
900
event = MouseEvent('motion_notify_event', self, x, y, self._button, self._key, guiEvent=guiEvent)
901
for func in self.callbacks.get('motion_notify_event', {}).values():
951
s = 'motion_notify_event'
952
event = MouseEvent(s, self, x, y, self._button, self._key,
954
self.callbacks.process(s, event)
904
956
def draw(self, *args, **kwargs):
936
988
filename - can also be a file object on image backends
937
989
orientation - only currently applies to PostScript printing.
938
990
dpi - the dots per inch to save the figure in; if None, use savefig.dpi
991
facecolor - the facecolor of the figure
992
edgecolor - the edgecolor of the figure
993
orientation - 'landscape' | 'portrait' (not supported on all backends)
960
1015
where event is a MplEvent. The following events are recognized
967
'button_release_event'
968
'motion_notify_event'
970
For the three events above, if the mouse is over the axes,
971
the variable event.inaxes will be set to the axes it is over,
972
and additionally, the variables event.xdata and event.ydata
973
will be defined. This is the mouse location in data coords.
974
See backend_bases.MplEvent.
1020
'key_release_event',
1021
'button_press_event',
1022
'button_release_event',
1023
'motion_notify_event',
1027
For the three events above, if the mouse is over the axes,
1028
the variable event.inaxes will be set to the axes it is over,
1029
and additionally, the variables event.xdata and event.ydata
1030
will be defined. This is the mouse location in data coords.
1031
See backend_bases.MplEvent.
976
1033
return value is a connection id that can be used with
977
1034
mpl_disconnect """
984
'button_press_event',
985
'button_release_event',
986
'motion_notify_event',
989
if s not in legit: raise ValueError('Unrecognized event "%s"'%s)
991
self.callbacks.setdefault(s, {})[self.cid] = func
1036
return self.callbacks.connect(s, func)
994
1038
def mpl_disconnect(self, cid):
996
Connect s to func. return an id that can be used with disconnect
997
Method should return None
1040
disconnect callback id cid
999
for eventname, callbackd in self.callbacks.items():
1000
if callbackd.has_key(cid):
1042
return self.callbacks.disconnect(cid)
1005
1045
class FigureManagerBase:
1414
1454
except OverflowError:
1415
1455
warnings.warn('Overflow while panning')
1417
a.set_xlim(self.nonsingular(xmin, xmax))
1418
a.set_ylim(self.nonsingular(ymin, ymax))
1457
a.set_xlim(xmin, xmax)
1458
a.set_ylim(ymin, ymax)
1420
1460
self.dynamic_update()
1422
def nonsingular(self, x0, x1):
1423
'''Desperate hack to prevent crashes when button-3 panning with
1424
axis('image') in effect.
1427
# much smaller thresholds seem to cause Value Error
1428
# later in Transformation::freeze in axes.draw()
1430
warnings.warn('Axis data limit is too small for panning')
1436
1462
def release_zoom(self, event):
1437
1463
'the release mouse button callback in zoom to rect mode'
1438
1464
if not self._xypress: return