python - cursor tracking using matplotlib and twinx -
i track coordinates of mouse respect data coordinates on 2 axes simultaneously. can track mouse position respect 1 axis fine. the problem is: when add second axis twinx()
, both cursors
report data coordinates respect second axis only.
for example, cursors (fern
, muffy
) report y
-value 7.93
fern: (1597.63, 7.93) muffy: (1597.63, 7.93)
if use:
inv = ax.transdata.inverted() x, y = inv.transform((event.x, event.y))
i indexerror.
so question is: how can modify code track data coordinates respect both axes?
import numpy np import matplotlib.pyplot plt import logging logger = logging.getlogger(__name__) class cursor(object): def __init__(self, ax, name): self.ax = ax self.name = name plt.connect('motion_notify_event', self) def __call__(self, event): x, y = event.xdata, event.ydata ax = self.ax # inv = ax.transdata.inverted() # x, y = inv.transform((event.x, event.y)) logger.debug('{n}: ({x:0.2f}, {y:0.2f})'.format(n=self.name,x=x,y=y)) logging.basicconfig(level=logging.debug, format='%(message)s',) fig, ax = plt.subplots() x = np.linspace(1000, 2000, 500) y = 100*np.sin(20*np.pi*(x-1500)/2000.0) fern = cursor(ax, 'fern') ax.plot(x,y) ax2 = ax.twinx() z = x/200.0 muffy = cursor(ax2, 'muffy') ax2.semilogy(x,z) plt.show()
due way call backs work, event returns in top axes. need bit of logic check if event happens in axes want:
class cursor(object): def __init__(self, ax, x, y, name): self.ax = ax self.name = name plt.connect('motion_notify_event', self) def __call__(self, event): if event.inaxes none: return ax = self.ax if ax != event.inaxes: inv = ax.transdata.inverted() x, y = inv.transform(np.array((event.x, event.y)).reshape(1, 2)).ravel() elif ax == event.inaxes: x, y = event.xdata, event.ydata else: return logger.debug('{n}: ({x:0.2f}, {y:0.2f})'.format(n=self.name,x=x,y=y))
this might subtle bug down in transform stack (or correct usage , luck worked tuples before), @ rate, make work. issue code @ line 1996 in transform.py
expects 2d ndarray
back, identity transform returns tuple handed it, generates errors.
Comments
Post a Comment