class_docstr: Class for creating and modifying the causal graph.
  
  Accepts a networkx DiGraph, a :py:class:`ProbabilisticCausalModel <dowhy.gcm.ProbabilisticCausalModel`, a graph string (or a text file) in gml format (preferred) or dot format. Graphviz-like attributes can be set for edges and nodes. E.g. style="dashed" as an edge attribute ensures that the edge is drawn with a dashed line.
  
   If a graph string is not given, names of treatment, outcome, and confounders, instruments and effect modifiers (if any) can be provided to create the graph.
class_docstr_tok: ["Class","for","creating","and","modifying","the","causal","graph",".","Accepts","a","networkx","DiGraph",",","a",":","py",":","class",":","`","ProbabilisticCausalModel","<","dowhy.gcm.ProbabilisticCausalModel","`",",","a","graph","string","(","or","a","text","file",")","in","gml","format","(","preferred",")","or","dot","format",".","Graphviz-like","attributes","can","be","set","for","edges","and","nodes",".","E.g",".","style=","''","dashed","''","as","an","edge","attribute","ensures","that","the","edge","is","drawn","with","a","dashed","line",".","If","a","graph","string","is","not","given",",","names","of","treatment",",","outcome",",","and","confounders",",","instruments","and","effect","modifiers","(","if","any",")","can","be","provided","to","create","the","graph","."]
code: def __init__(
      self,
      treatment_name,
      outcome_name,
      graph=None,
      common_cause_names=None,
      instrument_names=None,
      effect_modifier_names=None,
      mediator_names=None,
      observed_node_names=None,
      missing_nodes_as_confounders=False,
  ):
      self.treatment_name = parse_state(treatment_name)
      self.outcome_name = parse_state(outcome_name)
      instrument_names = parse_state(instrument_names)
      common_cause_names = parse_state(common_cause_names)
      effect_modifier_names = parse_state(effect_modifier_names)
      mediator_names = parse_state(mediator_names)
      self.logger = logging.getLogger(__name__)
  
      # re.sub only takes string parameter so the first if is to avoid error
      # if the input is a text file, convert the contained data into string
      if isinstance(graph, str) and re.match(r".*\.txt", str(graph)):
          text_file = open(graph, "r")
          graph = text_file.read()
          text_file.close()
  
      if isinstance(graph, str) and re.match(
          r"^dag", graph
      ):  # Convert daggity output to dot format
          graph = daggity_to_dot(graph)
  
      if isinstance(graph, str):
          graph = graph.replace("\n", " ")
  
      if graph is None:
          self._graph = nx.DiGraph()
          self._graph = self.build_graph(
              common_cause_names,
              instrument_names,
              effect_modifier_names,
              mediator_names,
          )
      elif isinstance(graph, nx.DiGraph):
          self._graph = nx.DiGraph(graph)
      elif isinstance(graph, ProbabilisticCausalModel):
          self._graph = nx.DiGraph(graph.graph)
      elif isinstance(graph, str) and re.match(r".*\.dot", graph):
          # load dot file
          try:
              import pygraphviz as pgv
  
              self._graph = nx.DiGraph(
                  nx.drawing.nx_agraph.read_dot(graph)
              )
          except Exception as e:
              self.logger.error(
                  "Pygraphviz cannot be loaded. "
                  + str(e)
                  + "\nTrying pydot..."
              )
              try:
                  import pydot
  
                  self._graph = nx.DiGraph(
                      nx.drawing.nx_pydot.read_dot(graph)
                  )
              except Exception as e:
                  self.logger.error(
                      "Error: Pydot cannot be loaded. " + str(e)
                  )
                  raise e
      elif isinstance(graph, str) and re.match(r".*\.gml", graph):
          self._graph = nx.DiGraph(nx.read_gml(graph))
      elif isinstance(graph, str) and re.match(
          r".*graph\s*\{.*\}\s*", graph
      ):
          try:
              import pygraphviz as pgv
  
              self._graph = pgv.AGraph(
                  graph, strict=True, directed=True
              )
              self._graph = nx.drawing.nx_agraph.from_agraph(
                  self._graph
              )
          except Exception as e:
              self.logger.error(
                  "Error: Pygraphviz cannot be loaded. "
                  + str(e)
                  + "\nTrying pydot ..."
              )
              try:
                  import pydot
  
                  P_list = pydot.graph_from_dot_data(graph)
                  self._graph = nx.DiGraph(
                      nx.drawing.nx_pydot.from_pydot(P_list[0])
                  )
              except Exception as e:
                  self.logger.error(
                      "Error: Pydot cannot be loaded. " + str(e)
                  )
                  raise e
      elif isinstance(graph, str) and re.match(
          ".*graph\s*\[.*\]\s*", graph
      ):
          self._graph = nx.DiGraph(nx.parse_gml(graph))
      else:
          error_msg = "Incorrect format: Please provide graph as a networkx DiGraph, GCM model, or as a string or text file in dot, gml format."
          self.logger.error(error_msg)
          self.logger.error("Error: Incorrect graph format")
          raise ValueError(error_msg)
  
      if observed_node_names is None and (
          isinstance(graph, nx.DiGraph)
          or isinstance(graph, ProbabilisticCausalModel)
      ):
          observed_node_names = list(self._graph.nodes)
      # TODO This functionality needs to be deprecated. It is a convenience function but can introduce confusion
      # as we are now including the option to initialize CausalGraph with DiGraph or GCM model.
      if missing_nodes_as_confounders:
          self._graph = self.add_missing_nodes_as_common_causes(
              observed_node_names
          )
      # Adding node attributes
      self._graph = self.add_node_attributes(observed_node_names)
  
imports: import itertools
  import logging
  import re
  import networkx
  from dowhy.gcm.causal_models import ProbabilisticCausalModel
  from dowhy.utils.api import parse_state
  from dowhy.utils.graph_operations import daggity_to_dot
  from dowhy.utils.plotting import plot
label_desc: Use image node_id 1 to create a new CausalGraph object  with example: obj = CausalGraph(treatment_name, outcome_name, graph, common_cause_names, instrument_names, effect_modifier_names, mediator_names, observed_node_names, missing_nodes_as_confounders)