class_docstr: A class of the initial plot object.
  
  Do not use this class explicitly.
  
  Instead, you should construct its objects with functions `ggplot()`,
  `corr_plot(...).points().build()` etc.
class_docstr_tok: ["A","class","of","the","initial","plot","object",".","Do","not","use","this","class","explicitly",".","Instead",",","you","should","construct","its","objects","with","functions","`","ggplot","(",")","`",",","`","corr_plot","(","...",")",".points","(",")",".build","(",")","`","etc","."]
docstr: Allow to add different specs to the `PlotSpec` object.
  
  Examples
  --------
  .. jupyter-execute::
      :linenos:
      :emphasize-lines: 7
  
      from lets_plot import *
      LetsPlot.setup_html()
      p = ggplot({'x': [0, 1, 2], 'y': [0, 1, 2]}, aes('x', 'y'))
      l = layer('point', mapping=aes(color='x'))
      s = scale_color_discrete()
      t = theme(axis_title='blank')
      p + l + s + t
code: def __add__(self, other):
      """
      Allow to add different specs to the `PlotSpec` object.
  
      Examples
      --------
      .. jupyter-execute::
          :linenos:
          :emphasize-lines: 7
  
          from lets_plot import *
          LetsPlot.setup_html()
          p = ggplot({'x': [0, 1, 2], 'y': [0, 1, 2]}, aes('x', 'y'))
          l = layer('point', mapping=aes(color='x'))
          s = scale_color_discrete()
          t = theme(axis_title='blank')
          p + l + s + t
  
      """
      """
              plot + other_plot -> fail
              plot + layer -> plot[layers] += layer
              plot + geom ->  plot[layers] += new layer(geom)
              plot + scale -> plot[scales] += scale
              plot + metainfo -> plot[metainfo_list] += metainfo
              plot + [feature]  -> plot + each feature in []
              plot + theme + theme -> merged theme
          """
      if isinstance(other, PlotSpec):
          # pass and fail
          pass
  
      if isinstance(other, DummySpec):
          # nothing
          return self
  
      elif isinstance(other, FeatureSpec):
          plot = PlotSpec.duplicate(self)
          if other.kind == "layer":
              if other.props()["geom"] == "livemap":
                  plot.__is_livemap = True
  
              from lets_plot.plot.util import (
                  is_geo_data_frame,
              )  # local import to break circular reference
  
              if is_geo_data_frame(
                  other.props().get("data")
              ) or is_geo_data_frame(other.props().get("map")):
                  if plot.__crs_initialized:
                      if plot.__crs != other.props().get("use_crs"):
                          raise ValueError(
                              "All geoms with map parameter should either use same `use_crs` or not use it at all"
                          )
                  else:
                      plot.__crs_initialized = True
                      plot.__crs = other.props().get("use_crs")
  
              if plot.__is_livemap and plot.__crs is not None:
                  raise ValueError("livemap doesn't support `use_crs`")
  
              other.before_append(plot.__is_livemap)
              plot.__layers.append(other)
              return plot
  
          if other.kind == "scale":
              plot.__scales.append(other)
              return plot
  
          if other.kind == "theme":
              new_theme_options = {
                  k: v
                  for k, v in other.props().items()
                  if v is not None
              }
              if "name" in new_theme_options:
                  # keep the previously specified flavor
                  if (
                      plot.props().get("theme", {}).get("flavor", None)
                      is not None
                  ):
                      new_theme_options.update(
                          {"flavor": plot.props()["theme"]["flavor"]}
                      )
  
                  # pre-configured theme overrides existing theme altogether.
                  plot.props()["theme"] = new_theme_options
              else:
                  # merge themes
                  old_theme_options = plot.props().get("theme", {})
                  plot.props()["theme"] = _theme_dicts_merge(
                      old_theme_options, new_theme_options
                  )
  
              return plot
  
          if other.kind == "metainfo":
              plot.__metainfo_list.append(other)
              return plot
  
          if isinstance(other, FeatureSpecArray):
              for spec in other.elements():
                  plot = plot.__add__(spec)
              return plot
  
          # add feature to properties
          plot.props()[other.kind] = other
          return plot
  
      return super().__add__(other)
  
imports: import io
  import json
  import os
  from typing import Union
  from lets_plot._global_settings import get_global_bool, has_global_value, FRAGMENTS_ENABLED
label_desc: Use image node_id 5 for calling the PlotSpec obj's underlying member method code with example usage: obj.__add__(other) and returns: super, self, plot, plot, plot, plot, plot, plot