code: def _collect_data_sources(
      self,
      repo: "Repo",
      targets: Optional[List[str]] = None,
      recursive: bool = False,
      props: Optional[Dict] = None,
      onerror: Optional[Callable] = None,
  ):
      fs = repo.dvcfs
  
      props = props or {}
  
      plots = _collect_plots(repo, targets, recursive)
      res: Dict[str, Any] = {}
      for fs_path, rev_props in plots.items():
          joined_props = {**rev_props, **props}
          res[fs_path] = {"props": joined_props}
          res[fs_path].update(
              {
                  "data_source": partial(
                      parse,
                      fs,
                      fs_path,
                      props=joined_props,
                      onerror=onerror,
                  )
              }
          )
      return res
  
imports: import csv
  import io
  import os
  from collections import defaultdict
  from copy import deepcopy
  from functools import partial
  from multiprocessing import cpu_count
  from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Set, Union
  import dpath
  import dpath.options
  from funcy import first, ldistinct, project, reraise
  from dvc.exceptions import DvcException
  from dvc.log import logger
  from dvc.utils import error_handler, errored_revisions
  from dvc.utils.objects import cached_property
  from dvc.utils.serialize import PARSERS, EncodingError
  from dvc.utils.threadpool import ThreadPoolExecutor
  from dvc_render.image import ImageRenderer
label_desc: Use image node_id 3 for calling the Plots obj's underlying member method code with example usage: obj._collect_data_sources(repo, targets, recursive, props, onerror) and returns: res