code: def _iplot(
      self,
      kind="scatter",
      data=None,
      layout=None,
      filename="",
      sharing=None,
      title="",
      xTitle="",
      yTitle="",
      zTitle="",
      theme=None,
      colors=None,
      colorscale=None,
      fill=False,
      width=None,
      dash="solid",
      mode="",
      interpolation="linear",
      symbol="circle",
      size=12,
      barmode="",
      sortbars=False,
      bargap=None,
      bargroupgap=None,
      bins=None,
      histnorm="",
      histfunc="count",
      orientation="v",
      boxpoints=False,
      annotations=None,
      keys=False,
      bestfit=False,
      bestfit_colors=None,
      mean=False,
      mean_colors=None,
      categories="",
      x="",
      y="",
      z="",
      text="",
      gridcolor=None,
      zerolinecolor=None,
      margin=None,
      labels=None,
      values=None,
      secondary_y="",
      secondary_y_title="",
      subplots=False,
      shape=None,
      error_x=None,
      error_y=None,
      error_type="data",
      locations=None,
      lon=None,
      lat=None,
      asFrame=False,
      asDates=False,
      asFigure=False,
      asImage=False,
      dimensions=None,
      asPlot=False,
      asUrl=False,
      online=None,
      **kwargs,
  ):
      """
             Returns a plotly chart either as inline chart, image of Figure object
  
             Parameters:
             -----------
                     kind : string
                             Kind of chart
                                     scatter
                                     bar
                                     box
                                     spread
                                     ratio
                                     heatmap
                                     surface
                                     histogram
                                     bubble
                                     bubble3d
                                     scatter3d
                                     scattergeo
                                     ohlc
                                     candle
                                     pie
                                     choroplet
                     data : Data
                             Plotly Data Object.
                             If not entered then the Data object will be automatically
                             generated from the DataFrame.
                     layout : Layout
                             Plotly layout Object
                             If not entered then the Layout objet will be automatically
                             generated from the DataFrame.
                     filename : string
                             Filename to be saved as in plotly account
                     sharing : string
                             Sets the sharing level permission
                                     public - anyone can see this chart
                                     private - only you can see this chart
                                     secret - only people with the link can see the chart
                     title : string
                             Chart Title
                     xTitle : string
                             X Axis Title
                     yTitle : string
                             Y Axis Title
                                     zTitle : string
                     zTitle : string
                             Z Axis Title
                             Applicable only for 3d charts
                     theme : string
                             Layout Theme
                                     solar
                                     pearl
                                     white
                             see cufflinks.getThemes() for all
                             available themes
                     colors : dict, list or string
                             {key:color} to specify the color for each column
                             [colors] to use the colors in the defined order
                     colorscale : string
                             Color scale name
                             If the color name is preceded by a minus (-)
                             then the scale is inversed
                             Only valid if 'colors' is null
                             See cufflinks.colors.scales() for available scales
                     fill : bool
                             Filled Traces
                     width : dict, list or int
                                     int : applies to all traces
                                     list : applies to each trace in the order
                                                     specified
                                     dict: {column:value} for each column in
                                                     the dataframe
                             Line width
                     dash : dict, list or string
                                     string : applies to all traces
                                     list : applies to each trace in the order
                                                     specified
                                     dict: {column:value} for each column in
                                                     the dataframe
                             Drawing style of lines
                                     solid
                                     dash
                                     dashdot
                                     dot
                     mode : dict, list or string
                                     string : applies to all traces
                                     list : applies to each trace in the order
                                                     specified
                                     dict: {column:value} for each column in
                                                     the dataframe
                             Plotting mode for scatter trace
                                     lines
                                     markers
                                     lines+markers
                                     lines+text
                                     markers+text
                                     lines+markers+text
                     interpolation : dict, list, or string
                                     string : applies to all traces
                                     list : applies to each trace in the order
                                                     specified
                                     dict: {column:value} for each column in
                                                     the dataframe
                             Positioning of the connecting lines
                                     linear
                                     spline
                                     vhv
                                     hvh
                                     vh
                                     hv
                     symbol : dict, list or string
                                     string : applies to all traces
                                     list : applies to each trace in the order
                                                     specified
                                     dict: {column:value} for each column in
                                                     the dataframe
                             The symbol that is drawn on the plot for each marker
                             Valid only when mode includes markers
                                     circle
                                     circle-dot
                                     diamond
                                     square
                                     and many more...(see plotly.validators.scatter.marker.SymbolValidator.values)
                     size : string or int
                             Size of marker
                             Valid only if marker in mode
                     barmode : string
                             Mode when displaying bars
                                     group
                                     stack
                                     overlay
                             * Only valid when kind='bar'
                     sortbars : bool
                             Sort bars in descending order
                             * Only valid when kind='bar'
                     bargap : float
                             Sets the gap between bars
                                     [0,1)
                             * Only valid when kind is 'histogram' or 'bar'
                     bargroupgap : float
                             Set the gap between groups
                                     [0,1)
                             * Only valid when kind is 'histogram' or 'bar'
                     bins : int or tuple
                             if int:
                                     Specifies the number of bins
                             if tuple:
                                     (start, end, size)
                                     start : starting value
                                     end: end value
                                     size: bin size
                             * Only valid when kind='histogram'
  
                     histnorm : string
                                     '' (frequency)
                                     percent
                                     probability
                                     density
                                     probability density
                             Sets the type of normalization for an histogram trace. By default
                             the height of each bar displays the frequency of occurrence, i.e.,
                             the number of times this value was found in the
                             corresponding bin. If set to 'percent', the height of each bar
                             displays the percentage of total occurrences found within the
                             corresponding bin. If set to 'probability', the height of each bar
                             displays the probability that an event will fall into the
                             corresponding bin. If set to 'density', the height of each bar is
                             equal to the number of occurrences in a bin divided by the size of
                             the bin interval such that summing the area of all bins will yield
                             the total number of occurrences. If set to 'probability density',
                             the height of each bar is equal to the number of probability that an
                             event will fall into the corresponding bin divided by the size of
                             the bin interval such that summing the area of all bins will yield
                             1.
                             * Only valid when kind='histogram'
                     histfunc : string
                                     count
                                     sum
                                     avg
                                     min
                                     max
                        Sets the binning function used for an histogram trace.
                             * Only valid when kind='histogram'
                     orientation : string
                                     h
                                     v
                             Sets the orientation of the bars. If set to 'v', the length of each
      |          bar will run vertically. If set to 'h', the length of each bar will
      |          run horizontally
                             * Only valid when kind is 'histogram','bar' or 'box'
                     boxpoints : string
                             Displays data points in a box plot
                                     outliers
                                     all
                                     suspectedoutliers
                                     False
                     annotations : dictionary
                             Dictionary of annotations
                             {x_point : text}
                     keys : list of columns
                             List of columns to chart.
                             Also can be used for custom sorting.
                     bestfit : boolean or list
                             If True then a best fit line will be generated for
                             all columns.
                             If list then a best fit line will be generated for
                             each key on the list.
                     bestfit_colors : list or dict
                             {key:color} to specify the color for each column
                             [colors] to use the colors in the defined order
                     categories : string
                             Name of the column that contains the categories
                     x : string
                             Name of the column that contains the x axis values
                     y : string
                             Name of the column that contains the y axis values
                     z : string
                             Name of the column that contains the z axis values
                     text : string
                             Name of the column that contains the text values
                     gridcolor : string
                             Grid color
                     zerolinecolor : string
                             Zero line color
                     margin : dict or tuple
                             Dictionary (l,r,b,t) or
                             Tuple containing the left,
                             right, bottom and top margins
                     labels : string
                             Name of the column that contains the labels.
                             * Only valid when kind='pie'
                     values : string
                             Name of the column that contains the values.
                             * Only valid when kind='pie'
                     secondary_y : string or list(string)
                             Name(s) of the column to be charted on the
                             right hand side axis
                     secondary_y_title : string
                             Title of the secondary axis
                     subplots : bool
                             If true then each trace is placed in
                             subplot layout
                     shape : (rows,cols)
                             Tuple indicating the size of rows and columns
                             If omitted then the layout is automatically set
                             * Only valid when subplots=True
                     error_x : int or float or [int or float]
                             error values for the x axis
                     error_y : int or float or [int or float]
                             error values for the y axis
                     error_type : string
                             type of error bars
                                     'data'
                                     'constant'
                                     'percent'
                                     'sqrt'
                                     'continuous'
                                     'continuous_percent'
                     asFrame : bool
                             If true then the data component of Figure will
                             be of Pandas form (Series) otherwise they will
                             be index values
                     asDates : bool
                             If true it truncates times from a DatetimeIndex
                     asFigure : bool
                             If True returns plotly Figure
                     asImage : bool
                             If True it returns an Image (png)
                             In ONLINE mode:
                                     Image file is saved in the working directory
                                             Accepts:
                                                     filename
                                                     dimensions
                                                     scale
                                                     display_image
                             In OFFLINE mode:
                                     Image file is downloaded (downloads folder) and a
                                     regular plotly chart is displayed in Jupyter
                                             Accepts:
                                                     filename
                                                     dimensions
                     dimensions : tuple(int,int)
                             Dimensions for image / chart
                                     (width,height)
                     asPlot : bool
                             If True the chart opens in browser
                     asUrl : bool
                             If True the chart url/path is returned. No chart is displayed.
                                     If Online : the URL is returned
                                     If Offline : the local path is returned
                     online : bool
                             If True then the chart/image is rendered on the server
                             even when running in offline mode.
  
                     Other Kwargs
                     ============
                     Line, Scatter
                             connectgaps : bool
                                     If True, empty values are connected
                     Pie charts
                             sort : bool
                                     If True it sorts the labels by value
                             pull : float [0-1]
                                     Pulls the slices from the centre
                             hole : float [0-1]
                                     Sets the size of the inner hole
                             linecolor : string
                                     Sets the color for the contour line of the slices
                             linewidth : string
                                     Sets the width for the contour line of the slices
                             textcolor : string
                                     Sets the color for the text in the slices
                             textposition : string
                                     Sets the position of the legends for each slice
                                             outside
                                             inner
                             textinfo : string
                                     Sets the information to be displayed on
                                     the legends
                                             label
                                             percent
                                             value
                                             * or ony combination of the above using
                                               '+' between each item
                                               ie 'label+percent'
  
                     Histogram
                             linecolor : string
                                     specifies the line color of the histogram
  
                     Heatmap and Surface
                             center_scale : float
                                     Centers the colorscale at a specific value
                                     Automatically sets the (zmin,zmax) values
                             zmin : float
                                     Defines the minimum range for the z values.
                                     This affects the range for the colorscale
                             zmax : float
                                     Defines the maximum range for the z values.
                                     This affects the range for the colorscale
  
                     Error Bars
                             error_trace : string
                                     Name of the column for which error should be
                                     plotted. If omitted then errors apply to all
                                     traces.
                             error_values_minus : int or float or [int or float]
                                     Values corresponding to the span of the error bars
                                     below the trace coordinates
                             error_color : string
                                     Color for error bars
                             error_thickness : float
                                     Sets the line thickness of the error bars
                             error_width :  float
                                     Sets the width (in pixels) of the cross-bar at both
                                     ends of the error bars
                             error_opacity : float [0,1]
                                     Opacity for the error bars
  
                     Subplots
                             horizontal_spacing : float [0,1]
                                     Space between subplot columns.
                             vertical_spacing : float [0,1]
                                     Space between subplot rows.
                             subplot_titles : bool
                                     If True, chart titles are plotted
                                     at the top of each subplot
                             shared_xaxes : bool
                                     Assign shared x axes.
                                     If True, subplots in the same grid column have one common
                                     shared x-axis at the bottom of the grid.
                             shared_yaxes : bool
                                     Assign shared y axes.
                                     If True, subplots in the same grid row have one common
                                     shared y-axis on the left-hand side of the grid.
  
                     Shapes
                             hline : float, list or dict
                                     Draws a horizontal line at the
                                     indicated y position(s)
                                     Extra parameters can be passed in
                                     the form of a dictionary (see shapes)
                             vline : float, list or dict
                                     Draws a vertical line at the
                                     indicated x position(s)
                                     Extra parameters can be passed in
                                     the form of a dictionary (see shapes)
                             hpsan : (y0,y1)
                                     Draws a horizontal rectangle at the
                                     indicated (y0,y1) positions.
                                     Extra parameters can be passed in
                                     the form of a dictionary (see shapes)
                             vspan : (x0,x1)
                                     Draws a vertical rectangle at the
                                     indicated (x0,x1) positions.
                                     Extra parameters can be passed in
                                     the form of a dictionary (see shapes)
                             shapes : dict or list(dict)
                                     List of dictionaries with the
                                     specifications of a given shape.
                                     See help(cufflinks.tools.get_shape)
                                     for more information
  
                     Axis Ranges
                             xrange : [lower_bound,upper_bound]
                                     Sets the range for the x axis
                             yrange : [lower_bound,upper_bound]
                                     Sets the range for the y axis
                             zrange : [lower_bound,upper_bound]
                                     Sets the range for the z axis
  
                     Explicit Layout Updates
                             layout_update : dict
                                     The layout will be modified with all
                                     the explicit values stated in the
                                     dictionary.
                                     It will not apply if layout is passed
                                     as parameter.
  
  
                     Range Selector
                             rangeselector : dict
                                     Defines a rangeselector object
                                     see help(cf.tools.get_range_selector) for more information
                                     Example:
                                             {'steps':['1y','2 months','5 weeks','ytd','2mtd'],
                                              'axis':'xaxis', 'bgcolor' : ('blue',.3),
                                              'x': 0.2 , 'y' : 0.9}
  
                     Range Slider
                             rangeslider : bool or dict
                                     Defines if a rangeslider is displayed
                                     If bool:
                                             True : Makes it visible
                                     if dict:
                                             Rangeslider object
                                     Example:
                                             {'bgcolor':('blue',.3),'autorange':True}
  
                     Annotations
                             fontcolor : str
                                     Text color for annotations
                             fontsize : int
                                     Text size for annotations
                             textangle : int
                                     Text angle
                             See https://plot.ly/python/reference/#layout-annotations
                             for a complete list of valid parameters.
  
                     Exports
                             display_image : bool
                                     If True then the image if displayed after being saved
                                     ** only valid if asImage=True
                             scale : integer
                                     Increase the resolution of the image by `scale` amount
                                     Only valid when asImage=True
      """
  
      # Valid Kwargs
      valid_kwargs = [
          "color",
          "opacity",
          "column",
          "columns",
          "labels",
          "text",
          "world_readable",
          "colorbar",
      ]
      BUBBLE_KWARGS = ["abs_size"]
      TRACE_KWARGS = ["hoverinfo", "connectgaps"]
      HEATMAP_SURFACE_KWARGS = ["center_scale", "zmin", "zmax"]
      PIE_KWARGS = [
          "sort",
          "pull",
          "hole",
          "textposition",
          "textinfo",
          "linecolor",
          "linewidth",
          "textcolor",
      ]
      OHLC_KWARGS = [
          "up_color",
          "down_color",
          "open",
          "high",
          "low",
          "close",
          "volume",
          "name",
          "decreasing",
          "increasing",
      ]
      SUBPLOT_KWARGS = [
          "horizontal_spacing",
          "vertical_spacing",
          "specs",
          "insets",
          "start_cell",
          "shared_xaxes",
          "shared_yaxes",
          "subplot_titles",
          "shared_xaxis",
          "shared_yaxis",
      ]
      GEO_KWARGS = ["locationmode", "locationsrc", "geo", "lon", "lat"]
      ERROR_KWARGS = [
          "error_trace",
          "error_values_minus",
          "error_color",
          "error_thickness",
          "error_width",
          "error_opacity",
      ]
      EXPORT_KWARGS = ["display_image", "scale"]
      FF_DISTPLOT = [
          "group_labels",
          "bin_size",
          "curve_type",
          "rug_text",
          "show_hist",
          "show_curve",
          "show_rug",
      ]
      FF_VIOLIN = ["data_header", "group_header", "show_rug", "sort"]
      kwargs_list = [
          tools.__LAYOUT_KWARGS,
          BUBBLE_KWARGS,
          TRACE_KWARGS,
          OHLC_KWARGS,
          PIE_KWARGS,
          HEATMAP_SURFACE_KWARGS,
          SUBPLOT_KWARGS,
          GEO_KWARGS,
          ERROR_KWARGS,
          EXPORT_KWARGS,
          FF_DISTPLOT,
          FF_VIOLIN,
      ]
      [valid_kwargs.extend(_) for _ in kwargs_list]
  
      dict_modifiers_keys = ["line"]
      dict_modifiers = {}
  
      for k in dict_modifiers_keys:
          dict_modifiers[k] = kwargs_from_keyword(kwargs, {}, k, True)
  
      for key in list(kwargs.keys()):
          if key not in valid_kwargs:
              raise Exception("Invalid keyword : '{0}'".format(key))
  
      # Setting default values
      if not colors:
          colors = kwargs["color"] if "color" in kwargs else colors
      if isinstance(colors, str):
          colors = [colors]
      opacity = kwargs["opacity"] if "opacity" in kwargs else 0.8
      if not dimensions:
          dimensions = auth.get_config_file()["dimensions"]
  
      # Get values from config theme
      if theme is None:
          theme = auth.get_config_file()["theme"]
      theme_config = tools.getTheme(theme)
      if colorscale is None:
          config_colorscale = auth.get_config_file()["colorscale"]
          if config_colorscale in ("dflt", None):
              colorscale = (
                  theme_config["colorscale"]
                  if "colorscale" in theme_config
                  else "original"
              )
          else:
              colorscale = config_colorscale
      if width is None:
          if kind != "pie":
              width = (
                  theme_config["linewidth"]
                  if "linewidth" in theme_config
                  else 2
              )
      if margin is None:
          margin = auth.get_config_file().get("margin", None)
  
      # In case column was used instead of keys
      if "column" in kwargs:
          keys = (
              [kwargs["column"]]
              if isinstance(kwargs["column"], str)
              else kwargs["column"]
          )
      if "columns" in kwargs:
          keys = (
              [kwargs["columns"]]
              if isinstance(kwargs["columns"], str)
              else kwargs["columns"]
          )
      kind = "line" if kind == "lines" else kind
  
      # Figure generators
      def get_marker(marker={}):
          if "line" in dict_modifiers:
              if "color" not in dict_modifiers["line"]:
                  if "linecolor" in kwargs:
                      linecolor = kwargs.get("linecolor")
                  else:
                      if "linecolor" in tools.getTheme(theme=theme):
                          linecolor = normalize(
                              tools.getTheme(theme=theme)["linecolor"]
                          )
                      else:
                          linecolor = tools.getLayout(theme=theme)[
                              "xaxis"
                          ]["titlefont"]["color"]
                  dict_modifiers["line"]["color"] = linecolor
              dict_modifiers["line"] = tools.updateColors(
                  dict_modifiers["line"]
              )
              marker["line"] = deep_update(
                  marker["line"], dict_modifiers["line"]
              )
          return marker
  
      # We assume we are good citizens
      validate = True
  
      if not layout:
          l_kwargs = dict(
              [
                  (k, kwargs[k])
                  for k in tools.__LAYOUT_KWARGS
                  if k in kwargs
              ]
          )
          if annotations:
              ann_kwargs = check_kwargs(
                  kwargs, tools.__ANN_KWARGS, clean_origin=True
              )
              annotations = tools.get_annotations(
                  self.copy(),
                  annotations,
                  kind=kind,
                  theme=theme,
                  **ann_kwargs,
              )
  
          layout = tools.getLayout(
              kind=kind,
              theme=theme,
              xTitle=xTitle,
              yTitle=yTitle,
              zTitle=zTitle,
              title=title,
              barmode=barmode,
              bargap=bargap,
              bargroupgap=bargroupgap,
              annotations=annotations,
              gridcolor=gridcolor,
              dimensions=dimensions,
              zerolinecolor=zerolinecolor,
              margin=margin,
              is3d="3d" in kind,
              **l_kwargs,
          )
      elif isinstance(layout, Layout):
          layout = layout.to_plotly_json()
  
      if not data:
          if categories and kind not in ("violin"):
              data = []
              if "bar" in kind:
                  df = self.copy()
                  df = df.set_index(categories)
                  fig = df.figure(
                      kind=kind,
                      colors=colors,
                      colorscale=colorscale,
                      fill=fill,
                      width=width,
                      sortbars=sortbars,
                      opacity=opacity,
                      asDates=asDates,
                      mode=mode,
                      symbol=symbol,
                      size=size,
                      text=text,
                      barmode=barmode,
                      orientation=orientation,
                  )
                  data = fig["data"]
              else:
                  _keys = pd.unique(self[categories])
                  colors = get_colors(colors, colorscale, _keys)
                  mode = "markers" if not mode else mode
                  for _ in _keys:
                      __ = self[self[categories] == _].copy()
                      if text:
                          _text = (
                              __[text] if asFrame else __[text].values
                          )
                      _x = __[x] if asFrame else __[x].values
                      _y = __[y] if asFrame else __[y].values
                      if z:
                          _z = __[z] if asFrame else __[z].values
                      if "bubble" in kind:
                          rg = __[size].values
                          rgo = self[size].values
                          if not kwargs.get("abs_size", False):
                              if len(rgo) > 1:
                                  _size = [
                                      int(
                                          100
                                          * (float(i) - rgo.min())
                                          / (rgo.max() - rgo.min())
                                      )
                                      + 12
                                      for i in rg
                                  ]
                              else:
                                  _size = [12] if len(rgo) else []
                          else:
                              _size = rgo
                      else:
                          _size = size
                      _data = Scatter3d(
                          x=_x,
                          y=_y,
                          mode=mode,
                          name=_,
                          marker=dict(
                              color=colors[_],
                              symbol=symbol,
                              size=_size,
                              opacity=opacity,
                              line=dict(width=width),
                          ),
                          textfont=tools.getLayout(theme=theme)[
                              "xaxis"
                          ]["titlefont"],
                      )
                      if "3d" in kind:
                          _data = Scatter3d(
                              x=_x,
                              y=_y,
                              z=_z,
                              mode=mode,
                              name=_,
                              marker=dict(
                                  color=colors[_],
                                  symbol=symbol,
                                  size=_size,
                                  opacity=opacity,
                                  line=dict(width=width),
                              ),
                              textfont=tools.getLayout(theme=theme)[
                                  "xaxis"
                              ]["titlefont"],
                          )
                      else:
                          # see error 168
                          if type(_x) == np.ndarray:
                              if "[ns]" in _x.dtype.str:
                                  _x = _x.astype(str)
                          if type(_y) == np.ndarray:
                              if "[ns]" in _y.dtype.str:
                                  _y = _y.astype(str)
  
                          _data = Scatter(
                              x=_x,
                              y=_y,
                              mode=mode,
                              name=_,
                              marker=dict(
                                  color=colors[_],
                                  symbol=symbol,
                                  size=_size,
                                  opacity=opacity,
                                  line=dict(width=width),
                              ),
                              textfont=tools.getLayout(theme=theme)[
                                  "xaxis"
                              ]["titlefont"],
                          )
                      if text:
                          _data.update(text=_text)
                      data.append(_data)
          else:
              if kind in (
                  "scatter",
                  "spread",
                  "ratio",
                  "bar",
                  "barh",
                  "area",
                  "line",
              ):
                  df = self.copy()
                  if type(df) == pd.core.series.Series:
                      df = pd.DataFrame({df.name: df})
                  if x:
                      df = df.set_index(x)
                  if y and secondary_y:
                      _y = [y] if not isinstance(y, list) else y
                      _secondary_y = (
                          [secondary_y]
                          if not isinstance(secondary_y, list)
                          else secondary_y
                      )
                      df = df[_y + _secondary_y]
                  elif y:
                      df = df[y]
                  if kind == "area":
                      df = df.transpose().fillna(0).cumsum().transpose()
                  mode = "lines" if not mode else mode
                  if text:
                      if not isinstance(text, list):
                          text = self[text].values
                  data = df.to_iplot(
                      colors=colors,
                      colorscale=colorscale,
                      kind=kind,
                      interpolation=interpolation,
                      fill=fill,
                      width=width,
                      dash=dash,
                      sortbars=sortbars,
                      keys=keys,
                      bestfit=bestfit,
                      bestfit_colors=bestfit_colors,
                      mean=mean,
                      mean_colors=mean_colors,
                      asDates=asDates,
                      mode=mode,
                      symbol=symbol,
                      size=size,
                      text=text,
                      **kwargs,
                  )
                  trace_kw = check_kwargs(kwargs, TRACE_KWARGS)
                  for trace in data:
                      trace.update(**trace_kw)
  
                  if kind in ("spread", "ratio"):
                      if kind == "spread":
                          trace = self.apply(
                              lambda x: x[0] - x[1], axis=1
                          )
                          positive = trace.apply(
                              lambda x: x if x >= 0 else np.nan
                          )
                          negative = trace.apply(
                              lambda x: x if x < 0 else np.nan
                          )
                          trace = pd.DataFrame(
                              {
                                  "positive": positive,
                                  "negative": negative,
                              }
                          )
                          trace = trace.to_iplot(
                              colors={
                                  "positive": "green",
                                  "negative": "red",
                              },
                              width=0.5,
                          )
                      else:
                          trace = self.apply(
                              lambda x: x[0] * 1.0 / x[1], axis=1
                          ).to_iplot(colors=["green"], width=1)
                      for t in trace:
                          t.update(
                              {
                                  "xaxis": "x2",
                                  "yaxis": "y2",
                                  "fill": "tozeroy",
                                  "name": kind.capitalize(),
                                  "connectgaps": False,
                                  "showlegend": False,
                              }
                          )
                      data.append(trace[0])
                      if kind == "spread":
                          data.append(trace[1])
                      layout["yaxis"].update({"domain": [0.3, 1]})
                      layout["yaxis2"] = copy.deepcopy(layout["yaxis"])
                      layout["xaxis2"] = copy.deepcopy(layout["xaxis"])
                      layout["yaxis2"].update(
                          domain=[0, 0.25], title=kind.capitalize()
                      )
                      layout["xaxis2"].update(
                          anchor="y2", showticklabels=False
                      )
                      layout["hovermode"] = "x"
                  if "bar" in kind:
                      if "stack" in barmode:
                          layout["legend"].update(traceorder="normal")
                      orientation = (
                          "h" if kind == "barh" else orientation
                      )
                      for trace in data:
                          trace.update(orientation=orientation)
                          if orientation == "h":
                              trace["x"], trace["y"] = (
                                  trace["y"],
                                  trace["x"],
                              )
  
              elif kind == "bubble":
                  mode = "markers" if "markers" not in mode else mode
                  x = self[x].values.tolist()
                  y = self[y].values.tolist()
                  z = size if size else z
                  rg = self[z].values
                  if not kwargs.get("abs_size", False):
                      if len(rg) > 1:
                          z = [
                              int(
                                  100
                                  * (float(_) - rg.min())
                                  / (rg.max() - rg.min())
                              )
                              + 12
                              for _ in rg
                          ]
                      else:
                          z = [12] if len(rg) else []
                  else:
                      z = rg
                  text = (
                      kwargs["labels"] if "labels" in kwargs else text
                  )
                  labels = self[text].values.tolist() if text else ""
                  clrs = colors if colors else get_scales(colorscale)
                  clrs = [clrs] if not isinstance(clrs, list) else clrs
                  clrs = [clrs[0]] * len(x) if len(clrs) == 1 else clrs
                  marker = dict(
                      color=clrs,
                      size=z,
                      symbol=symbol,
                      line=dict(width=width),
                  )
                  trace = Scatter(
                      x=x,
                      y=y,
                      marker=marker,
                      mode="markers",
                      text=labels,
                  )
                  data = [trace]
              elif kind in ("box", "histogram", "hist"):
                  if isinstance(self, pd.core.series.Series):
                      df = pd.DataFrame({self.name: self})
                  else:
                      df = self.copy()
                  data = []
                  clrs = get_colors(colors, colorscale, df.columns)
                  if "hist" in kind:
                      barmode = "overlay" if barmode == "" else barmode
                      layout.update(barmode=barmode)
                  columns = keys if keys else df.columns
                  for _ in columns:
                      if kind == "box":
                          __ = Box(
                              y=df[_].values.tolist(),
                              marker=dict(color=clrs[_]),
                              name=_,
                              line=dict(width=width),
                              boxpoints=boxpoints,
                          )
                          # 114 - Horizontal Box
                          __["orientation"] = orientation
                          if orientation == "h":
                              __["x"], __["y"] = __["y"], __["x"]
  
                      else:
                          __ = dict(
                              x=df[_].values.tolist(),
                              name=_,
                              marker=dict(
                                  color=clrs[_], line=dict(width=width)
                              ),
                              orientation=orientation,
                              opacity=kwargs["opacity"]
                              if "opacity" in kwargs
                              else 0.8,
                              histfunc=histfunc,
                              histnorm=histnorm,
                          )
  
                          __["marker"] = get_marker(__["marker"])
  
                          if orientation == "h":
                              __["y"] = __["x"]
                              del __["x"]
                          __ = Histogram(__)
                          if bins:
                              if type(bins) in (tuple, list):
                                  try:
                                      _bins = {
                                          "start": bins[0],
                                          "end": bins[1],
                                          "size": bins[2],
                                      }
                                      if orientation == "h":
                                          __.update(
                                              ybins=_bins,
                                              autobiny=False,
                                          )
                                      else:
                                          __.update(
                                              xbins=_bins,
                                              autobinx=False,
                                          )
                                  except:
                                      print(
                                          "Invalid format for bins generation"
                                      )
                              else:
                                  if orientation == "h":
                                      __.update(nbinsy=bins)
                                  else:
                                      __.update(nbinsx=bins)
                      data.append(__)
  
              elif kind in ("heatmap", "surface"):
                  if x:
                      x = self[x].values.tolist()
                  else:
                      if self.index.__class__.__name__ in (
                          "PeriodIndex",
                          "DatetimeIndex",
                      ):
                          x = self.index.format()
                      else:
                          x = self.index.values.tolist()
                  y = (
                      self[y].values.tolist()
                      if y
                      else self.columns.values.tolist()
                  )
                  z = (
                      self[z].values.tolist()
                      if z
                      else self.values.transpose()
                  )
                  scale = (
                      get_scales("rdbu")
                      if not colorscale
                      else get_scales(colorscale)
                  )
                  scale = [normalize(_) for _ in scale]
                  colorscale = [
                      [float(_) / (len(scale) - 1), scale[_]]
                      for _ in range(len(scale))
                  ]
                  center_scale = kwargs.get("center_scale", None)
  
                  if is_list(z):
                      zmin = min(z)
                      zmax = max(z)
                  else:
                      zmin = z.min()
                      zmax = z.max()
  
                  if center_scale is not None:
                      if center_scale <= zmin + (zmax - zmin) / 2:
                          zmin = center_scale * 2 - zmax
                      else:
                          zmax = center_scale * 2 - zmin
                  zmin = kwargs.get("zmin", zmin)
                  zmax = kwargs.get("zmax", zmax)
                  if kind == "heatmap":
                      data = [
                          Heatmap(
                              z=z,
                              x=x,
                              y=y,
                              zmin=zmin,
                              zmax=zmax,
                              colorscale=colorscale,
                          )
                      ]
                  else:
                      data = [
                          Surface(z=z, x=x, y=y, colorscale=colorscale)
                      ]
  
              elif kind in ("scatter3d", "bubble3d"):
                  data = []
                  keys = (
                      self[text].values
                      if text
                      else list(range(len(self)))
                  )
                  colors = get_colors(
                      colors, colorscale, keys, asList=True
                  )
                  mode = "markers" if "markers" not in mode else mode
                  df = self.copy()
                  df["index"] = keys
                  if kind == "bubble3d":
                      rg = self[size].values
                      if not kwargs.get("abs_size", False):
                          size = [
                              int(
                                  100
                                  * (float(_) - rg.min())
                                  / (rg.max() - rg.min())
                              )
                              + 12
                              for _ in rg
                          ]
                      else:
                          size = rg
                  else:
                      size = [size for _ in range(len(keys))]
  
                  _data = Scatter3d(
                      x=df[x].values.tolist(),
                      y=df[y].values.tolist(),
                      z=df[z].values.tolist(),
                      mode=mode,
                      text=keys,
                      marker=dict(
                          color=colors,
                          symbol=symbol,
                          size=size,
                          opacity=0.8,
                      ),
                  )
                  if text:
                      _data.update(text=keys)
                  data.append(_data)
  
              elif kind == "pie":
                  if not labels:
                      raise CufflinksError("Missing: labels")
                  if not values:
                      raise CufflinksError("Missing: values")
                  labels = self[labels].values.tolist()
                  values = self[values].values.tolist()
                  marker = dict(
                      colors=get_colors(
                          colors, colorscale, labels, asList=True
                      )
                  )
                  marker.update(
                      line=dict(
                          color=kwargs.pop("linecolor", None),
                          width=kwargs.pop("linewidth", width),
                      )
                  )
                  pie = dict(
                      values=values,
                      labels=labels,
                      name="",
                      marker=marker,
                  )
  
                  kw = check_kwargs(kwargs, PIE_KWARGS)
                  kw["textfont"] = {"color": kw.pop("textcolor", None)}
                  pie.update(kw)
                  data = []
                  del layout["xaxis"]
                  del layout["yaxis"]
                  data.append(Pie(pie))
                  validate = False
  
              elif kind in ("old_candle", "old_ohlc"):
                  d = ta._ohlc_dict(self)
                  if len(list(d.keys())) != 4:
                      raise Exception(
                          "OHLC type of charts require an Open, High, Low and Close column"
                      )
                  ohlc_kwargs = check_kwargs(kwargs, OHLC_KWARGS)
                  if kind == "old_candle":
                      fig = tools.get_candle(
                          self,
                          theme=theme,
                          layout=layout,
                          **ohlc_kwargs,
                      )
                  else:
                      fig = tools.get_ohlc(
                          self,
                          theme=theme,
                          layout=layout,
                          **ohlc_kwargs,
                      )
                  if bestfit:
                      df = self.copy()
                      bf = _to_iplot(
                          self[d["close"]],
                          bestfit=True,
                          bestfit_colors=bestfit_colors,
                          asTimestamp=True,
                      )
                      fig["data"].append(bf[1])
                  data = fig["data"]
                  layout = fig["layout"]
  
              elif kind in ("candle", "ohlc", "candlestick"):
                  kind = "candlestick" if kind == "candle" else kind
                  kw = check_kwargs(kwargs, OHLC_KWARGS)
                  d = ta._ohlc_dict(self, validate="ohlc", **kw)
                  _d = dict(
                      type=kind,
                      open=self[d["open"]].values.tolist(),
                      high=self[d["high"]].values.tolist(),
                      low=self[d["low"]].values.tolist(),
                      close=self[d["close"]].values.tolist(),
                  )
                  if isinstance(
                      self.index,
                      pd.core.indexes.datetimes.DatetimeIndex,
                  ):
                      _d["x"] = self.index.astype("str")
                  else:
                      _d["x"] = self.index
                  if "name" in kw:
                      _d["name"] = kw["name"]
  
                  showlegend = False
                  if "showlegend" in kwargs:
                      showlegend = kwargs["showlegend"]
                  else:
                      if "legend" in kwargs:
                          if type(kwargs["legend"]) == bool:
                              showlegend = kwargs["legend"]
                  # https://github.com/santosjorge/cufflinks/issues/113
                  # _d['increasing']=dict(line=dict(color=kw['up_color']) if 'up_color' in kw else dict(),showlegend=showlegend)
                  # _d['decreasing']=dict(line=dict(color=kw['down_color']) if 'down_color' in kw else dict(),showlegend=showlegend)
                  _d["increasing"] = dict(
                      line=dict(color=kw["up_color"])
                      if "up_color" in kw
                      else dict()
                  )
                  _d["decreasing"] = dict(
                      line=dict(color=kw["down_color"])
                      if "down_color" in kw
                      else dict()
                  )
                  for k in ("increasing", "decreasing"):
                      if k in kw:
                          _d[k] = deep_update(_d[k], kw[k])
  
                  _d["showlegend"] = showlegend
                  _d["yaxis"] = "y2"
                  data = [_d]
  
              elif kind in ("choropleth", "scattergeo"):
                  kw = check_kwargs(kwargs, GEO_KWARGS)
                  if kind == "choropleth":
                      if not all([x != None for x in (locations, z)]):
                          raise Exception(
                              "Choropleth maps require a 'location' and 'z' column names specified"
                          )
                      geo_data = {
                          "type": "choropleth",
                          "locations": self[locations],
                          "z": self[z],
                          "colorscale": get_colorscale(colorscale),
                          "marker": get_marker(
                              dict(line=dict(width=width))
                          ),
                      }
                  elif kind == "scattergeo":
                      if not all([x != None for x in (lon, lat)]):
                          raise Exception(
                              "Scattergeo maps require a 'lon' and 'lat' column names specified"
                          )
                      geo_data = {
                          "type": "scattergeo",
                          "lat": self[lat],
                          "lon": self[lon],
                          "marker": get_marker(
                              dict(
                                  line=dict(width=width),
                                  symbol=symbol,
                                  colorscale=get_colorscale(colorscale),
                                  color=self[z] if z else None,
                              )
                          ),
                      }
                  if "colorbar" in kwargs:
                      geo_data["colorbar"] = kwargs["colorbar"]
                  geo_data.update(kw)
                  if text:
                      geo_data.update(text=self[text])
                  validate = False
                  data = []
                  data.append(geo_data)
  
              # Figure Factory
              elif kind in ("distplot"):
                  colors = get_colors(
                      colors, colorscale, self.keys(), asList=True
                  )
                  hist_data = self.transpose().values
                  kw = check_kwargs(kwargs, FF_DISTPLOT)
                  group_labels = kw.pop("group_labels", self.columns)
                  if histnorm:
                      kw["histnorm"] = histnorm
                  fig = ff.create_distplot(
                      hist_data=hist_data,
                      group_labels=group_labels,
                      colors=colors,
                      **kw,
                  ).to_dict()
                  data = fig["data"]
                  layout = tools.merge_dict(layout, fig["layout"])
              elif kind in ("violin"):
                  df = (
                      pd.DataFrame(self)
                      if type(self) == pd.core.series.Series
                      else self.copy()
                  )
                  kw = check_kwargs(kwargs, FF_VIOLIN)
                  kw["rugplot"] = kw.pop("show_rug", True)
                  kw["title"] = title
                  if "group_header" not in kw:
                      kw["group_header"] = (
                          categories if categories else None
                      )
                  categories = kw.get("group_header")
                  colors = get_colors(
                      colors,
                      colorscale,
                      df[categories].value_counts().values
                      if categories
                      else df.keys(),
                      asList=True,
                  )
                  kw["colors"] = colors
                  if categories:
                      for _ in range(
                          2, df[categories].value_counts().size + 1
                      ):
                          layout["xaxis{0}".format(_)] = layout[
                              "xaxis"
                          ].copy()
                      if categories not in df:
                          raise CufflinksError(
                              'Column "{0}" not found in DataFrame'.format(
                                  categories
                              )
                          )
                      elif len(df.columns) == 1:
                          raise CufflinksError(
                              'When "categories" are specified, two columns are expected. \n Only one column was found.'
                          )
                      elif len(df.columns) == 2:
                          cols = list(df.columns)
                          cols.remove(categories)
                          kw["data_header"] = cols[0]
                      else:
                          if "data_header" not in kw:
                              raise CufflinksError(
                                  "data_header must be the column name with the desired numeric data for the violin plot."
                              )
                  else:
                      if len(df.columns) == 1:
                          kw["data_header"] = df.columns[0]
                      elif len(df.columns) > 1:
                          if "data_header" not in kw:
                              raise CufflinksError(
                                  "data_header must be the column name with the desired numeric data for the violin plot."
                              )
                  fig = ff.create_violin(df, **kw).to_dict()
                  data = fig["data"]
                  layout = tools.merge_dict(layout, fig["layout"])
  
      ## Sharing Values
      if all(["world_readable" in kwargs, sharing is None]):
          sharing = kwargs["world_readable"]
      if isinstance(sharing, bool):
          if sharing:
              sharing = "public"
          else:
              sharing = "private"
      if sharing is None:
          sharing = auth.get_config_file()["sharing"]
  
      if not filename:
          if title:
              filename = title
          else:
              filename = "Plotly Playground {0}".format(
                  time.strftime("%Y-%m-%d %H:%M:%S")
              )
  
      ## Figure defintion
      figure = {}
      figure["data"] = data
      figure["layout"] = layout
  
      ## Check secondary axis
      if secondary_y:
          figure = tools._set_axis(figure, secondary_y, side="right")
          if secondary_y_title:
              figure.layout.yaxis2.title = secondary_y_title
  
      ## Error Bars
      if kind in ("scatter", "bar", "barh", "lines", "line"):
          if any([error_x, error_y]):
  
              def set_error(axis, **kwargs):
                  return tools.set_errors(figure, axis=axis, **kwargs)
  
              kw = check_kwargs(kwargs, ERROR_KWARGS)
              kw = dict(
                  [
                      (k.replace("error_", ""), v)
                      for k, v in list(kw.items())
                  ]
              )
              kw["type"] = error_type
              if error_x:
                  kw["values"] = error_x
                  figure = set_error("x", **kw)
              if error_y:
                  kw["values"] = error_y
                  figure = set_error("y", **kw)
      ## Subplots
  
      if subplots:
          fig = tools.strip_figures(figure)
          kw = check_kwargs(kwargs, SUBPLOT_KWARGS)
          for _ in ["x", "y"]:
              if "shared_{0}axes".format(_) not in kw:
                  kw["shared_{0}axes".format(_)] = kw.pop(
                      "shared_{0}axis".format(_), False
                  )
          if "subplot_titles" in kwargs:
              if kwargs["subplot_titles"] == True:
                  kw["subplot_titles"] = [d["name"] for d in data]
              else:
                  kw["subplot_titles"] = kwargs["subplot_titles"]
          figure = tools.subplots(
              fig, shape, base_layout=layout, theme=theme, **kw
          )
  
      ## Exports
      validate = False if "shapes" in layout else validate
  
      if asFigure:
          return Figure(figure)
      else:
          return iplot(
              figure,
              validate=validate,
              sharing=sharing,
              filename=filename,
              online=online,
              asImage=asImage,
              asUrl=asUrl,
              asPlot=asPlot,
              dimensions=dimensions,
              display_image=kwargs.get("display_image", True),
          )
  
imports: import pandas
  import time
  import copy
  import numpy
  from plotly.graph_objs import Figure, Layout, Bar, Box, Scatter, FigureWidget, Scatter3d, Histogram, Heatmap, Surface, Pie
  import plotly.figure_factory
  from collections import defaultdict
  from IPython.display import display, Image
  from .exceptions import CufflinksError
  from .colors import normalize, get_scales, colorgen, to_rgba, get_colorscale
  from .utils import check_kwargs, deep_update, kwargs_from_keyword, is_list
  from .None import tools
  from .None import offline
  from .None import auth
  from .None import ta
label_desc: Use image node_id 4 for calling a global function with example usage: _iplot(kind, data, layout, filename, sharing, title, xTitle, yTitle, zTitle, theme, colors, colorscale, fill, width, dash, mode, interpolation, symbol, size, barmode, sortbars, bargap, bargroupgap, bins, histnorm, histfunc, orientation, boxpoints, annotations, keys, bestfit, bestfit_colors, mean, mean_colors, categories, x, y, z, text, gridcolor, zerolinecolor, margin, labels, values, secondary_y, secondary_y_title, subplots, shape, error_x, error_y, error_type, locations, lon, lat, asFrame, asDates, asFigure, asImage, dimensions, asPlot, asUrl, online) and returns: marker, Figure, iplot, tools