Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    MultiCursor horizontal and vertical lines invisible

    General Code/Help
    1
    2
    190
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • weibudda
      weibudda last edited by

      In the matplotlib's multicursor example:

      import numpy as np
      import matplotlib.pyplot as plt
      from matplotlib.widgets import MultiCursor
      
      t = np.arange(0.0, 2.0, 0.01)
      s1 = np.sin(2*np.pi*t)
      s2 = np.sin(4*np.pi*t)
      
      fig, (ax1, ax2) = plt.subplots(2, sharex=True)
      ax1.plot(t, s1)
      ax2.plot(t, s2)
      
      multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1)
      plt.show()
      

      The horizontal and vertical lines is visible. Why in the backtrader situation, the are disappeared?

      I checked the MultiCursor source code in backtrader,

      class MultiCursor(Widget):
          """
          Provide a vertical (default) and/or horizontal line cursor shared between
          multiple axes.
      
          For the cursor to remain responsive you much keep a reference to
          it.
      
          Example usage::
      
              from matplotlib.widgets import MultiCursor
              from pylab import figure, show, np
      
              t = np.arange(0.0, 2.0, 0.01)
              s1 = np.sin(2*np.pi*t)
              s2 = np.sin(4*np.pi*t)
              fig = figure()
              ax1 = fig.add_subplot(211)
              ax1.plot(t, s1)
      
      
              ax2 = fig.add_subplot(212, sharex=ax1)
              ax2.plot(t, s2)
      
              multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
                                  horizOn=False, vertOn=True)
              show()
      
          """
          def __init__(self, canvas, axes, useblit=True,
                       horizOn=False, vertOn=True,
                       horizMulti=False, vertMulti=True,
                       horizShared=True, vertShared=False,
                       **lineprops):
      
              self.canvas = canvas
              self.axes = axes
              self.horizOn = horizOn
              self.vertOn = vertOn
              self.horizMulti = horizMulti
              self.vertMulti = vertMulti
      
              self.visible = True
              self.useblit = useblit and self.canvas.supports_blit
              self.background = None
              self.needclear = False
      
              if self.useblit:
                  lineprops['animated'] = True
      
              self.vlines = []
              if vertOn:
                  xmin, xmax = axes[-1].get_xlim()
                  xmid = 0.5 * (xmin + xmax)
      
                  for ax in axes:
                      if not horizShared:
                          xmin, xmax = ax.get_xlim()
                          xmid = 0.5 * (xmin + xmax)
      
                      vline = ax.axvline(xmid, visible=False, **lineprops)
                      self.vlines.append(vline)
      
              self.hlines = []
              if horizOn:
                  ymin, ymax = axes[-1].get_ylim()
                  ymid = 0.5 * (ymin + ymax)
      
                  for ax in axes:
                      if not vertShared:
                          ymin, ymax = ax.get_ylim()
                          ymid = 0.5 * (ymin + ymax)
      
                      hline = ax.axhline(ymid, visible=False, **lineprops)
                      self.hlines.append(hline)
      
              self.connect()
      
          def connect(self):
              """connect events"""
              self._cidmotion = self.canvas.mpl_connect('motion_notify_event',
                                                        self.onmove)
              self._ciddraw = self.canvas.mpl_connect('draw_event', self.clear)
      
          def disconnect(self):
              """disconnect events"""
              self.canvas.mpl_disconnect(self._cidmotion)
              self.canvas.mpl_disconnect(self._ciddraw)
      
          def clear(self, event):
              """clear the cursor"""
              if self.ignore(event):
                  return
              if self.useblit:
                  self.background = (
                      self.canvas.copy_from_bbox(self.canvas.figure.bbox))
              for line in self.vlines + self.hlines:
                  line.set_visible(False)
      
          def onmove(self, event):
              if self.ignore(event):
                  return
              if event.inaxes is None:
                  return
              if not self.canvas.widgetlock.available(self):
                  return
              self.needclear = True
              if not self.visible:
                  return
              if self.vertOn:
                  for line in self.vlines:
                      visible = self.visible
                      if not self.vertMulti:
                          visible = visible and line.axes == event.inaxes
      
                      if visible:
                          line.set_xdata((event.xdata, event.xdata))
                          line.set_visible(visible)
              if self.horizOn:
                  for line in self.hlines:
                      visible = self.visible
                      if not self.horizMulti:
                          visible = visible and line.axes == event.inaxes
                      if visible:
                          line.set_ydata((event.ydata, event.ydata))
                          line.set_visible(self.visible)
              self._update(event)
      
          def _update(self, event):
              if self.useblit:
                  if self.background is not None:
                      self.canvas.restore_region(self.background)
                  if self.vertOn:
                      for ax, line in zip(self.axes, self.vlines):
                          if self.vertMulti or event.inaxes == line.axes:
                              ax.draw_artist(line)
      
                  if self.horizOn:
                      for ax, line in zip(self.axes, self.hlines):
                          if self.horizMulti or event.inaxes == line.axes:
                              ax.draw_artist(line)
                  self.canvas.blit(self.canvas.figure.bbox)
              else:
                  self.canvas.draw_idle()
      

      and compared it to the one in matplotlib:

      class MultiCursor(Widget):
          """
          Provide a vertical (default) and/or horizontal line cursor shared between
          multiple axes.
      
          For the cursor to remain responsive you must keep a reference to
          it.
      
          Example usage::
      
              from matplotlib.widgets import MultiCursor
              import matplotlib.pyplot as plt
              import numpy as np
      
              fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
              t = np.arange(0.0, 2.0, 0.01)
              ax1.plot(t, np.sin(2*np.pi*t))
              ax2.plot(t, np.sin(4*np.pi*t))
      
              multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
                                  horizOn=False, vertOn=True)
              plt.show()
      
          """
         def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=True,
                       **lineprops):
      
              self.canvas = canvas
              self.axes = axes
              self.horizOn = horizOn
              self.vertOn = vertOn
      
              xmin, xmax = axes[-1].get_xlim()
              ymin, ymax = axes[-1].get_ylim()
              xmid = 0.5 * (xmin + xmax)
              ymid = 0.5 * (ymin + ymax)
      
              self.visible = True
              self.useblit = useblit and self.canvas.supports_blit
              self.background = None
              self.needclear = False
      
              if self.useblit:
                  lineprops['animated'] = True
      
              if vertOn:
                  self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
                                 for ax in axes]
              else:
                  self.vlines = []
      
              if horizOn:
                  self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
                                 for ax in axes]
              else:
                  self.hlines = []
      
              self.connect()
      
        def connect(self):
              """connect events"""
              self._cidmotion = self.canvas.mpl_connect('motion_notify_event',
                                                        self.onmove)
              self._ciddraw = self.canvas.mpl_connect('draw_event', self.clear)
      
      
          def disconnect(self):
              """disconnect events"""
              self.canvas.mpl_disconnect(self._cidmotion)
              self.canvas.mpl_disconnect(self._ciddraw)
      
         def clear(self, event):
              """clear the cursor"""
              if self.ignore(event):
                  return
              if self.useblit:
                  self.background = (
                      self.canvas.copy_from_bbox(self.canvas.figure.bbox))
              for line in self.vlines + self.hlines:
                  line.set_visible(False)
      
          def onmove(self, event):
              if self.ignore(event):
                  return
              if event.inaxes is None:
                  return
              if not self.canvas.widgetlock.available(self):
                  return
              self.needclear = True
              if not self.visible:
                  return
              if self.vertOn:
                  for line in self.vlines:
                      line.set_xdata((event.xdata, event.xdata))
                      line.set_visible(self.visible)
              if self.horizOn:
                  for line in self.hlines:
                      line.set_ydata((event.ydata, event.ydata))
                      line.set_visible(self.visible)
              self._update()
      
      
          def _update(self):
              if self.useblit:
                  if self.background is not None:
                      self.canvas.restore_region(self.background)
                  if self.vertOn:
                      for ax, line in zip(self.axes, self.vlines):
                          ax.draw_artist(line)
                  if self.horizOn:
                      for ax, line in zip(self.axes, self.hlines):
                          ax.draw_artist(line)
                  self.canvas.blit(self.canvas.figure.bbox)
              else:
                  self.canvas.draw_idle()
      

      Nothing is wrong. What's the problem? Any suggestions?

      1 Reply Last reply Reply Quote 0
      • weibudda
        weibudda last edited by

        Problem solved. Simply modify block=True in plot.py:

         def show(self):
                self.mpyplot.show(block=True)
        
        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors