code: def _analyze(
      dataset_name: str,
      dataset: Dataset,
      force: bool,
      countplots: bool,
      directory: Union[None, str, pathlib.Path],
  ):
      from . import analysis
  
      plt, sns = _get_plotting_libraries()
  
      # Raise matplotlib level
      logging.getLogger("matplotlib").setLevel(logging.WARNING)
  
      if directory is None:
          directory = PYKEEN_DATASETS
      else:
          directory = pathlib.Path(directory)
          directory.mkdir(exist_ok=True, parents=True)
  
      d = directory.joinpath(dataset_name, "analysis")
      d.mkdir(parents=True, exist_ok=True)
  
      dfs = {}
      it = tqdm(analysis.__dict__.items(), leave=False, desc="Stats")
      for name, func in it:
          if not name.startswith("get") or not name.endswith("df"):
              continue
          it.set_postfix(func=name)
          key = name[len("get_") : -len("_df")]
          path = d.joinpath(key).with_suffix(".tsv")
          if path.exists() and not force:
              df = pd.read_csv(path, sep="\t")
          else:
              df = func(dataset=dataset)
              df.to_csv(
                  d.joinpath(key).with_suffix(".tsv"),
                  sep="\t",
                  index=False,
              )
          dfs[key] = df
  
      fig, ax = plt.subplots(1, 1)
      sns.scatterplot(
          data=dfs["relation_injectivity"],
          x=LABEL_HEAD,
          y=LABEL_TAIL,
          size="support",
          hue="support",
          ax=ax,
      )
      ax.set_title(
          f'{docdata.get_docdata(dataset.__class__)["name"]} Relation Injectivity'
      )
      fig.tight_layout()
      fig.savefig(d.joinpath("relation_injectivity.svg"))
      plt.close(fig)
  
      fig, ax = plt.subplots(1, 1)
      sns.scatterplot(
          data=dfs["relation_functionality"],
          x="functionality",
          y="inverse_functionality",
          ax=ax,
      )
      ax.set_title(
          f'{docdata.get_docdata(dataset.__class__)["name"]} Relation Functionality'
      )
      fig.tight_layout()
      fig.savefig(d.joinpath("relation_functionality.svg"))
      plt.close(fig)
  
      if countplots:
          entity_count_df = (
              dfs["entity_count"]
              .groupby("entity_label")
              .sum()
              .reset_index()
              .sort_values("count", ascending=False)
          )
          fig, ax = plt.subplots(1, 1)
          sns.barplot(
              data=entity_count_df, y="entity_label", x="count", ax=ax
          )
          ax.set_ylabel("")
          ax.set_xscale("log")
          fig.tight_layout()
          fig.savefig(d.joinpath("entity_counts.svg"))
          plt.close(fig)
  
          relation_count_df = (
              dfs["relation_count"]
              .groupby("relation_label")
              .sum()
              .reset_index()
              .sort_values("count", ascending=False)
          )
          fig, ax = plt.subplots(1, 1)
          sns.barplot(
              data=relation_count_df,
              y="relation_label",
              x="count",
              ax=ax,
          )
          ax.set_ylabel("")
          ax.set_xscale("log")
          fig.tight_layout()
          fig.savefig(d.joinpath("relation_counts.svg"))
          plt.close(fig)
  
imports: import itertools
  import json
  import logging
  import math
  import pathlib
  from textwrap import dedent
  from typing import Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union
  import click
  import docdata
  import pandas
  import scipy.stats
  from more_click import force_option, log_level_option, verbose_option
  from tqdm import tqdm
  from tqdm.contrib.logging import logging_redirect_tqdm
  from .base import Dataset
  from .utils import dataset_regex_option, iter_dataset_instances, max_triples_option, min_triples_option
  from ..constants import COLUMN_LABELS, PYKEEN_DATASETS
  from ..evaluation.evaluator import get_candidate_set_size
  from ..metrics.ranking import ArithmeticMeanRank, GeometricMeanRank, HarmonicMeanRank, HitsAtK, InverseArithmeticMeanRank, InverseGeometricMeanRank, InverseHarmonicMeanRank, InverseMedianRank, MedianRank
  from ..triples import CoreTriplesFactory
  from ..typing import LABEL_HEAD, LABEL_RELATION, LABEL_TAIL, SIDE_MAPPING, ExtendedTarget
label_desc: Use image node_id 4 for calling a global function with example usage: _analyze(dataset_name, dataset, force, countplots, directory) without return types