class_docstr: SmartPlotter is a Bridge pattern decoupling plotting functions from SmartExplainer.
  The smartplotter class includes all the methods used to display graphics
  Each SmartPlotter method is easy to use from a Smart explainer object,
  just use the following syntax
  Attributes :
  explainer: object
      SmartExplainer instance to point to.
  Example
  --------
  >>> xpl.plot.my_plot_method(param=value)
class_docstr_tok: ["SmartPlotter","is","a","Bridge","pattern","decoupling","plotting","functions","from","SmartExplainer",".","The","smartplotter","class","includes","all","the","methods","used","to","display","graphics","Each","SmartPlotter","method","is","easy","to","use","from","a","Smart","explainer","object",",","just","use","the","following","syntax","Attributes",":","explainer",":","object","SmartExplainer","instance","to","point","to",".","Example","--","--","--","--",">",">",">","xpl.plot.my_plot_method","(","param=value",")"]
docstr: Plot features importance computed with the prediction set.
  Parameters
  ----------
  feature_imp1 : pd.Series
      Feature importance computed with every rows
  feature_imp2 : pd.Series, optional (default: None)
      The contributions associate
  title : str
      Title of the plot, default set to 'Features Importance'
  addnote : String (default: None)
      Specify a note to display
  subtitle : String (default: None)
      Subtitle to display
  width : Int (default: 900)
      Plotly figure - layout width
  height : Int (default: 500)
      Plotly figure - layout height
  file_name: string (optional)
      Specify the save path of html files. If it is not provided, no file will be saved.
  auto_open: bool (default=False)
      open automatically the plot
  zoom: bool (default=False)
      graph is currently zoomed
code: def plot_features_import(
      self,
      feature_imp1,
      feature_imp2=None,
      title="Features Importance",
      addnote=None,
      subtitle=None,
      width=900,
      height=500,
      file_name=None,
      auto_open=False,
      zoom=False,
  ):
      """
      Plot features importance computed with the prediction set.
      Parameters
      ----------
      feature_imp1 : pd.Series
          Feature importance computed with every rows
      feature_imp2 : pd.Series, optional (default: None)
          The contributions associate
      title : str
          Title of the plot, default set to 'Features Importance'
      addnote : String (default: None)
          Specify a note to display
      subtitle : String (default: None)
          Subtitle to display
      width : Int (default: 900)
          Plotly figure - layout width
      height : Int (default: 500)
          Plotly figure - layout height
      file_name: string (optional)
          Specify the save path of html files. If it is not provided, no file will be saved.
      auto_open: bool (default=False)
          open automatically the plot
      zoom: bool (default=False)
          graph is currently zoomed
      """
      dict_t = copy.deepcopy(self._style_dict["dict_title"])
      topmargin = 80
      # Add subtitle and / or addnote
      if subtitle or addnote:
          # title += f"<span style='font-size: 12px;'><br />{add_text([subtitle, addnote], sep=' - ')}</span>"
          if subtitle and addnote:
              title += (
                  "<br><sup>" + subtitle + " - " + addnote + "</sup>"
              )
          elif subtitle:
              title += "<br><sup>" + subtitle + "</sup>"
          else:
              title += "<br><sup>" + addnote + "</sup>"
          topmargin = topmargin + 15
      dict_t.update(text=title)
      dict_xaxis = copy.deepcopy(self._style_dict["dict_xaxis"])
      dict_xaxis.update(text="Mean absolute Contribution")
      dict_yaxis = copy.deepcopy(self._style_dict["dict_yaxis"])
      dict_yaxis.update(text=None)
      dict_style_bar1 = self._style_dict["dict_featimp_colors"][1]
      dict_style_bar2 = self._style_dict["dict_featimp_colors"][2]
      dict_yaxis["text"] = None
  
      # Change bar color for groups of features
      marker_color = [
          self._style_dict["featureimp_groups"][0]
          if (
              self.explainer.features_groups is not None
              and self.explainer.inv_features_dict.get(
                  f.replace("<b>", "").replace("</b>", "")
              )
              in self.explainer.features_groups.keys()
          )
          else dict_style_bar1["color"]
          for f in feature_imp1.index
      ]
  
      layout = go.Layout(
          barmode="group",
          template="none",
          autosize=False,
          width=width,
          height=height,
          title=dict_t,
          xaxis_title=dict_xaxis,
          yaxis_title=dict_yaxis,
          hovermode="closest",
          margin={"l": 160, "r": 0, "t": topmargin, "b": 50},
      )
      # To change ticktext when the x label size is upper than 30 and zoom is False
      if (type(feature_imp1.index[0]) == str) & (not zoom):
          # change index to abc...abc if its length is upper than 30
          index_val = [
              y.replace(y[24 : len(y) - 3], "...") if len(y) > 30 else y
              for y in feature_imp1.index
          ]
      else:
          index_val = feature_imp1.index
      bar1 = go.Bar(
          x=feature_imp1.round(4),
          y=feature_imp1.index,
          orientation="h",
          name="Global",
          marker=dict_style_bar1,
          marker_color=marker_color,
          hovertemplate="Feature: %{customdata}<br />Contribution: %{x:.4f}<extra></extra>",
          customdata=feature_imp1.index,
      )
      if feature_imp2 is not None:
          bar2 = go.Bar(
              x=feature_imp2.round(4),
              y=feature_imp2.index,
              orientation="h",
              name="Subset",
              marker=dict_style_bar2,
              hovertemplate="Feature: %{customdata}<br />Contribution: %{x:.4f}<extra></extra>",
              customdata=feature_imp2.index,
          )
          data = [bar2, bar1]
      else:
          data = bar1
  
      fig = go.Figure(data=data, layout=layout)
      # Update ticktext
      fig.update_yaxes(
          ticktext=index_val,
          tickvals=feature_imp1.index,
          tickmode="array",
          dtick=1,
      )
      fig.update_yaxes(automargin=True)
      if file_name:
          plot(fig, filename=file_name, auto_open=auto_open)
      return fig
  
imports: import warnings
  from numbers import Number
  import random
  import copy
  import math
  import numpy
  from scipy.optimize import fsolve
  import scipy.cluster.hierarchy
  import pandas
  from plotly import graph_objs
  import plotly.express
  from plotly.subplots import make_subplots
  from plotly.offline import plot
  from shapash.manipulation.select_lines import select_lines
  from shapash.manipulation.summarize import compute_features_import, project_feature_values_1d, compute_corr
  from shapash.utils.utils import add_line_break, truncate_str, compute_digit_number, add_text, maximum_difference_sort_value, compute_sorted_variables_interactions_list_indices, compute_top_correlations_features
  from shapash.webapp.utils.utils import round_to_k
  from shapash.style.style_utils import colors_loading, select_palette, define_style
label_desc: Use image node_id 8 for calling the SmartPlotter obj's underlying member method code with example usage: obj.plot_features_import(feature_imp1, feature_imp2, title, addnote, subtitle, width, height, file_name, auto_open, zoom) and returns: fig