我一直在试错修改上述解决方案,直到它做到了我认为我想要的。
"""
Interatively zoom plots together, but permit them to scroll independently.
"""
from matplotlib import pyplot
import sys
def _get_limits( ax ):
""" Return X and Y limits for the passed axis as [[xlow,xhigh],[ylow,yhigh]]
"""
return [list(ax.get_xlim()), list(ax.get_ylim())]
def _set_limits( ax, lims ):
""" Set X and Y limits for the passed axis
"""
ax.set_xlim(*(lims[0]))
ax.set_ylim(*(lims[1]))
return
def pre_zoom( fig ):
""" Initialize history used by the re_zoom() event handler.
Call this after plots are configured and before pyplot.show().
"""
global oxy
oxy = [_get_limits(ax) for ax in fig.axes]
return
def re_zoom(event):
""" Pyplot event handler to zoom all plots together, but permit them to
scroll independently. Created to support eyeball correlation.
Use with 'motion_notify_event' and 'button_release_event'.
"""
global oxy
for ax in event.canvas.figure.axes:
navmode = ax.get_navigate_mode()
if navmode is not None:
break
scrolling = (event.button == 1) and (navmode == "PAN")
if scrolling:
oxy = [_get_limits(ax) for ax in event.canvas.figure.axes]
return
if event.name != 'button_release_event':
return
zooming = (navmode == "ZOOM") or ((event.button == 3) and (navmode == "PAN"))
if not zooming:
oxy = [_get_limits(ax) for ax in event.canvas.figure.axes]
return
changed = None
zoom = [[0.0,0.0],[0.0,0.0]]
for i, ax in enumerate(event.canvas.figure.axes):
nxy = _get_limits(ax)
if (oxy[i] != nxy):
changed = i
for j in [0,1]:
width = oxy[i][j][1] - oxy[i][j][0]
zoom[j] = [(nxy[j][0] - oxy[i][j][0]) / width,
(oxy[i][j][1] - nxy[j][1]) / width]
break
if changed is not None:
for i, ax in enumerate(event.canvas.figure.axes):
if i == changed:
continue
for j in [0,1]:
width = oxy[i][j][1] - oxy[i][j][0]
nxy[j] = [oxy[i][j][0] + (width*zoom[j][0]),
oxy[i][j][1] - (width*zoom[j][1])]
_set_limits(ax, nxy)
event.canvas.draw()
pre_zoom(event.canvas.figure)
return
def main(argv):
""" Test/demo code for re_zoom() event handler.
"""
import numpy
x = numpy.linspace(0,100,1000)
y = numpy.sin(x)*(1+x)
fig = pyplot.figure()
ax1 = pyplot.subplot(211)
ax1.plot(x,y)
ax2 = pyplot.subplot(212)
ax2.plot(x,y)
pre_zoom( fig )
pyplot.connect('motion_notify_event', re_zoom)
pyplot.connect('button_release_event',re_zoom)
pyplot.show()
if __name__ == "__main__":
main(sys.argv)