Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 91eb1a9

Browse files
committed
Merge pull request #1811 from davidtrem/multicursor
MultiCursor with additionnal optionnal horizontal bar
2 parents 4ac6780 + 500f1cf commit 91eb1a9

File tree

2 files changed

+50
-18
lines changed

2 files changed

+50
-18
lines changed

doc/api/api_changes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ Changes in 1.3.x
2727
* The `~matplotlib.mpl` module is now deprecated. Those who relied on this
2828
module should transition to simply using `import matplotlib as mpl`.
2929

30+
* The extension of :class:`~matplotlib.widgets.MultiCursor` to both vertical
31+
(default) and/or horizontal cursor implied that ``self.line`` is replaced
32+
by ``self.vline`` for vertical cursors lines and ``self.hline`` is added
33+
for the horizontal cursors lines.
34+
3035
Changes in 1.2.x
3136
================
3237

lib/matplotlib/widgets.py

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from transforms import blended_transform_factory
1919
from matplotlib import MatplotlibDeprecationWarning as mplDeprecation
2020

21+
2122
class LockDraw:
2223
"""
2324
Some widgets, like the cursor, draw onto the canvas, and this is not
@@ -829,7 +830,8 @@ class Cursor(AxesWidget):
829830
830831
and the visibility of the cursor itself with the *visible* attribute
831832
"""
832-
def __init__(self, ax, horizOn=True, vertOn=True, useblit=False, **lineprops):
833+
def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,
834+
**lineprops):
833835
"""
834836
Add a cursor to *ax*. If ``useblit=True``, use the backend-
835837
dependent blitting features for faster updates (GTKAgg
@@ -907,7 +909,8 @@ def _update(self):
907909

908910
class MultiCursor(Widget):
909911
"""
910-
Provide a vertical line cursor shared between multiple axes
912+
Provide a vertical (default) and/or horizontal line cursor shared between
913+
multiple axes
911914
912915
Example usage::
913916
@@ -925,16 +928,23 @@ class MultiCursor(Widget):
925928
ax2 = fig.add_subplot(212, sharex=ax1)
926929
ax2.plot(t, s2)
927930
928-
multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1)
931+
multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
932+
horizOn=False, vertOn=True)
929933
show()
930934
931935
"""
932-
def __init__(self, canvas, axes, useblit=True, **lineprops):
936+
def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=True,
937+
**lineprops):
933938

934939
self.canvas = canvas
935940
self.axes = axes
941+
self.horizOn = horizOn
942+
self.vertOn = vertOn
943+
936944
xmin, xmax = axes[-1].get_xlim()
945+
ymin, ymax = axes[-1].get_ylim()
937946
xmid = 0.5 * (xmin + xmax)
947+
ymid = 0.5 * (ymin + ymax)
938948

939949
self.visible = True
940950
self.useblit = useblit and self.canvas.supports_blit
@@ -943,18 +953,28 @@ def __init__(self, canvas, axes, useblit=True, **lineprops):
943953

944954
if useblit:
945955
lineprops['animated'] = True
946-
self.lines = [ax.axvline(xmid, visible=False, **lineprops)
947-
for ax in axes]
956+
957+
if vertOn:
958+
self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
959+
for ax in axes]
960+
else:
961+
self.vlines = []
962+
963+
if horizOn:
964+
self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
965+
for ax in axes]
966+
else:
967+
self.hlines = []
948968

949969
self.canvas.mpl_connect('motion_notify_event', self.onmove)
950970
self.canvas.mpl_connect('draw_event', self.clear)
951971

952972
def clear(self, event):
953973
"""clear the cursor"""
954974
if self.useblit:
955-
self.background = self.canvas.copy_from_bbox(
956-
self.canvas.figure.bbox)
957-
for line in self.lines:
975+
self.background = (
976+
self.canvas.copy_from_bbox(self.canvas.figure.bbox))
977+
for line in self.vlines + self.hlines:
958978
line.set_visible(False)
959979

960980
def onmove(self, event):
@@ -965,19 +985,26 @@ def onmove(self, event):
965985
self.needclear = True
966986
if not self.visible:
967987
return
968-
969-
for line in self.lines:
970-
line.set_xdata((event.xdata, event.xdata))
971-
line.set_visible(self.visible)
988+
if self.vertOn:
989+
for line in self.vlines:
990+
line.set_xdata((event.xdata, event.xdata))
991+
line.set_visible(self.visible)
992+
if self.horizOn:
993+
for line in self.hlines:
994+
line.set_ydata((event.ydata, event.ydata))
995+
line.set_visible(self.visible)
972996
self._update()
973997

974998
def _update(self):
975-
976999
if self.useblit:
9771000
if self.background is not None:
9781001
self.canvas.restore_region(self.background)
979-
for ax, line in zip(self.axes, self.lines):
980-
ax.draw_artist(line)
1002+
if self.vertOn:
1003+
for ax, line in zip(self.axes, self.vlines):
1004+
ax.draw_artist(line)
1005+
if self.horizOn:
1006+
for ax, line in zip(self.axes, self.hlines):
1007+
ax.draw_artist(line)
9811008
self.canvas.blit(self.canvas.figure.bbox)
9821009
else:
9831010

@@ -1349,7 +1376,7 @@ def ignore(self, event):
13491376
# boundaries.
13501377
if event.button == self.eventpress.button and event.inaxes != self.ax:
13511378
(xdata, ydata) = self.ax.transData.inverted().transform_point(
1352-
(event.x, event.y))
1379+
(event.x, event.y))
13531380
x0, x1 = self.ax.get_xbound()
13541381
y0, y1 = self.ax.get_ybound()
13551382
xdata = max(x0, xdata)
@@ -1407,7 +1434,7 @@ def release(self, event):
14071434
yproblems = self.minspany is not None and spany < self.minspany
14081435

14091436
if (((self.drawtype == 'box') or (self.drawtype == 'line')) and
1410-
(xproblems or yproblems)):
1437+
(xproblems or yproblems)):
14111438
# check if drawn distance (if it exists) is not too small in
14121439
# neither x nor y-direction
14131440
return

0 commit comments

Comments
 (0)