I am just studying this matplotlib example, but don't understand the dot syntax:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
class DraggablePoint:
lock = None #only one can be animated at a time
def __init__(self, point):
self.point = point
self.press = None
self.background = None
def connect(self):
'connect to all the events we need'
self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event', self.on_release)
self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
def on_press(self, event):
if event.inaxes != self.point.axes: return
if DraggablePoint.lock is not None: return
contains, attrd = self.point.contains(event)
if not contains: return
self.press = (self.point.center), event.xdata, event.ydata
DraggablePoint.lock = self
# draw everything but the selected rectangle and store the pixel buffer
canvas = self.point.figure.canvas
axes = self.point.axes
self.point.set_animated(True)
canvas.draw()
self.background = canvas.copy_from_bbox(self.point.axes.bbox)
# now redraw just the rectangle
axes.draw_artist(self.point)
# and blit just the redrawn area
canvas.blit(axes.bbox)
def on_motion(self, event):
if DraggablePoint.lock is not self:
return
if event.inaxes != self.point.axes: return
self.point.center, xpress, ypress = self.press
dx = event.xdata - xpress
dy = event.ydata - ypress
self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)
canvas = self.point.figure.canvas
axes = self.point.axes
# restore the background region
canvas.restore_region(self.background)
# redraw just the current rectangle
axes.draw_artist(self.point)
# blit just the redrawn area
canvas.blit(axes.bbox)
def on_release(self, event):
'on release we reset the press data'
if DraggablePoint.lock is not self:
return
self.press = None
DraggablePoint.lock = None
# turn off the rect animation property and reset the background
self.point.set_animated(False)
self.background = None
# redraw the full figure
self.point.figure.canvas.draw()
def disconnect(self):
'disconnect all the stored connection ids'
self.point.figure.canvas.mpl_disconnect(self.cidpress)
self.point.figure.canvas.mpl_disconnect(self.cidrelease)
self.point.figure.canvas.mpl_disconnect(self.cidmotion)
fig = plt.figure()
ax = fig.add_subplot(111)
drs = []
circles = [patches.Circle((0.32, 0.3), 0.03, fc='r', alpha=0.5),
patches.Circle((0.3,0.3), 0.03, fc='g', alpha=0.5)]
for circ in circles:
ax.add_patch(circ)
dr = DraggablePoint(circ)
dr.connect()
drs.append(dr)
plt.show()
Now take for example the line
ax.add_patch(circ)
This seems to be pretty clear to me. The axes
class has a method called add_patch
which takes (in particular) Circle
objects as argument. So ax.add_patch(circ)
just calls this method from the object ax
which is an axes
instance.
The dot in import matplotlib.patches
seems to have a different meaning. It just accesses the module patches
which is a submodule of matplotlib
see http://matplotlib.org/1.3.1/py-modindex.html for a list of modules.
And a module as I understand it is just a Python file containing some classes and functions.
Now consider:
self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.point
is the point
variable defined in init (which doesn't need to be a fixed type). Later in the code there are DraggablePoint
objects instantiated via dr = DraggablePoint(circ)
where circ
is a patches.Circle
object. Now I struggle to interpret self.point.figure
. The figure
in this case cannot be a function since there is no ()
at the end.
For me it also doesn't make sense to see it as module in this case. I guess it is a type of shorthand for something like self.point.get_current_figure()
which returns the figure where the point is drawn on.
Similarly the self.point.figure.canvas
seems to be something like self.point.get_current_figure().get_canvas()
which returns the current canvas. However there seems to be no get_current_figure
or get_canvas
methods in the mathplotlib.patches.Circ
class resp. the mathmatplotlib.figure.Figure
class (see:
http://matplotlib.org/1.3.1/api/artist_api.html#module-matplotlib.patches and http://matplotlib.org/1.3.1/api/figure_api.html#matplotlib.figure.Figure).
So it would be great if someone could clarify this for me. And more generally:
There seems to be multiple different meanings of dot notation in Python. Which are there, how are they called and how do I know which one is used?
How can I see that I can call
self.point.figure
orself.point.figure.canvas
from the matplotlib API docs? As noted above I didn't find it in the docs.