code: def _crawl_sources(
      sources: Sequence[Path],
  ) -> Tuple[pd.DataFrame, Collection[BenchmarkMetadata]]:
      results_df_list = []
      results_metadata = []
      visited = set()
      queue = list(sources)
      while queue:
          source = queue.pop()
  
          source = source.resolve()
          assert source.is_dir()
          # Sym-links can cause cycles - don't visit the same directory multiple times...
          if source in visited:
              continue
          visited.add(source)
  
          metrics_df_path = source / "metrics.csv"
          metadata_path = source / "metadata.json"
          if metrics_df_path.exists() or metadata_path.exists():
              assert metrics_df_path.exists()
              assert metadata_path.exists()
              results_df_list.append(pd.read_csv(metrics_df_path))
              with open(metadata_path, "rt") as f:
                  results_metadata.append(
                      BenchmarkMetadata.from_json(json.load(f))
                  )
  
          for child in source.iterdir():
              if child.is_dir():
                  queue.append(child)
  
      results_df = pd.concat(
          results_df_list, axis="index", ignore_index=True
      )
      return results_df, results_metadata
  
file_path: GPflow/benchmark/plot.py
imports: import argparse
  import json
  from pathlib import Path
  from typing import Collection, Sequence, Tuple
  import matplotlib.pyplot
  import pandas
  import benchmark.benchmarks
  import benchmark.metrics
  from benchmark.benchmark_api import BENCHMARK_SUITES, BenchmarkSuite
  from benchmark.grouping import group
  from benchmark.metadata import BenchmarkMetadata
  from benchmark.paths import setup_dest
label_desc: Use image node_id 1 for calling a global function with example usage: _crawl_sources(sources) and returns: results_df,  results_metadata