docs: def on_canvas_slave__electrode_pair_selected(self, slave, data):
          '''
          Process pair of selected electrodes.
  
          For now, this consists of finding the shortest path between the two
          electrodes and appending it to the list of droplet routes for the
          current step.
  
          Note that the droplet routes for a step are stored in a frame/table in
          the `DmfDeviceController` step options.
  
  
          .. versionchanged:: 0.11
              Clear any temporary routes (drawn while mouse is down) from routes
              list.
  
          .. versionchanged:: 0.11.3
              Clear temporary routes by setting ``df_routes`` property of
              :attr:`canvas_slave`.
          '''
          import networkx as nx
  
          source_id = data['source_id']
          target_id = data['target_id']
  
          if self.canvas_slave.device is None or self.plugin is None:
              return
          # XXX Negative `route_i` corresponds to temporary route being
          # drawn.  Since electrode pair selection terminates route drawing,
          # clear any rows corresponding to negative `route_i` values from the
          # routes table.
          slave.df_routes = slave.df_routes.loc[slave.df_routes.route_i >=
                                                0].copy()
          try:
              shortest_path = self.canvas_slave.device.find_path(source_id,
                                                                 target_id)
              self.plugin.execute_async('droplet_planning_plugin',
                                        'add_route', drop_route=shortest_path)
          except nx.NetworkXNoPath:
              logger.error('No path found between %s and %s.', source_id,
                           target_id)