code: def bar_plot(
      values: Dict[str, float],
      uncertainties: Optional[Dict[str, Tuple[float, float]]] = None,
      ylabel: str = "",
      filename: Optional[str] = None,
      display_plot: bool = True,
      figure_size: Optional[List[int]] = None,
      bar_width: float = 0.8,
      xticks: List[str] = None,
      xticks_rotation: int = 90,
      sort_names: bool = False,
  ) -> None:
      """Convenience function to make a bar plot of the given values with uncertainty bars, if provided. Useful for all
      kinds of attribution results (including confidence intervals).
  
      :param values: A dictionary where the keys are the labels and the values are the values to be plotted.
      :param uncertainties: A dictionary of attributes to be added to the error bars.
      :param ylabel: The label for the y-axis.
      :param filename: An optional filename if the output should be plotted into a file.
      :param display_plot: Optionally specify if the plot should be displayed or not (default to True).
      :param figure_size: The size of the figure to be plotted.
      :param bar_width: The width of the bars.
      :param xticks: Explicitly specify the labels for the bars on the x-axis.
      :param xticks_rotation: Specify the rotation of the labels on the x-axis.
      :param sort_names: If True, the names in the plot are sorted alphabetically. If False, the order as given in values
                         are used.
      """
      if sort_names:
          values = {k: values[k] for k in sorted(values)}
  
          if xticks is not None:
              xticks = sorted(xticks)
  
      if uncertainties is None:
          uncertainties = {
              node: [values[node], values[node]] for node in values
          }
      else:
          for node in values:
              if node not in uncertainties:
                  uncertainties[node] = [values[node], values[node]]
  
      figure, ax = plt.subplots(figsize=figure_size)
      ci_plus = np.array(
          [
              uncertainties[node][1] - values[node]
              for node in values.keys()
          ]
      )
      ci_minus = np.array(
          [
              values[node] - uncertainties[node][0]
              for node in values.keys()
          ]
      )
  
      is_negative_yerr = np.logical_or(ci_plus < 0, ci_minus < 0)
      ci_plus[is_negative_yerr] = 0
      ci_minus[is_negative_yerr] = 0
  
      yerr = np.array([ci_minus, ci_plus])
      plt.bar(
          values.keys(),
          values.values(),
          yerr=yerr,
          ecolor="#1E88E5",
          color="#ff0d57",
          width=bar_width,
      )
      plt.ylabel(ylabel)
      plt.xticks(rotation=xticks_rotation)
  
      ax.spines["right"].set_visible(False)
      ax.spines["top"].set_visible(False)
      if xticks:
          plt.xticks(list(uncertainties.keys()), xticks)
  
      if display_plot:
          plt.show()
  
      if filename is not None:
          figure.savefig(filename)
  
file_path: dowhy/dowhy/utils/plotting.py
imports: import logging
  import os
  import tempfile
  from typing import Any, Dict, List, Optional, Tuple, Union
  import matplotlib.pyplot
  import networkx
  import numpy
  import pandas
  from matplotlib import image
label_desc: Use image node_id 3 for calling a global function with example usage: bar_plot(values, uncertainties, ylabel, filename, display_plot, figure_size, bar_width, xticks, xticks_rotation, sort_names) without return types