v.0.18

2023.04.25

The package shimoku-api-python is no longer maintained

To get the new version 🦾

pip install --upgrade shimoku-api-python

This version expands massively the charts catalog as well as bringing a new navigation tool!

Fixes

Horizontal indicators group now occupies all available columns given. Previously, if the number of indicators didn't divide the number of columns, sometimes the sum of the sizes of the indicators didn't equal the number of given columns. The remaining space is now filled with padding.

Improvements

  • New HTML Component

    A new component has been added to the shimoku_components_catalog library! It is an iteration on the previous title component, it brings a lot more features and customization options:

    def create_h1_title_with_modal(
        title: str, 
        subtitle: str, 
        # This will be the title shown in the modal, if the value is None, the 
        # information icon will not be shown, and the modal will not be available
        modal_title: Optional[str] = None,
        # Information icon
        icon_url: str = 'https://uploads-ssl.webflow.com/619f9fe98661d321dc3beec7/63594ccf3f311a98d72faff7_suite-customer-b.svg',
        # Text shown in the modal
        modal_text: str = "You can click the X in the corner or click the overlay to close this modal. "
    		      "This is a nice way to show additional information.",
        # Main title color
        text_color: str = 'var(--background-paper)',
        # Main background color
        background_color: str = 'var(--color-black)', 
        # Information icon default color
        modal_icon_color: str = 'var(--chart-C1)',
        # Information icon hover color
        modal_icon_hover_color: str = 'var(--color-primary-dark)'
    ) -> str:

    This next example shows a basic configuration of the component that uses the primary colors palette:

    s.plt.html(
        menu_path=menu_path, order=0,
        html = s.html_components.create_h1_title_with_modal(
            title='New HTML Component', subtitle='modal and title',
            text_color='var(--color-white)', background_color='var(--color-primary)',
            modal_title='Modal Title',
        ),
    )

    The modal used in this component is not the same as the report Modal!

  • The new navigation tool added is the Modal report! A Modal report is a type of container report that allows you to include other reports inside of it, much like a Tabs report. When a Modal report is opened, it appears as a pop-up window that overlays the current page. This report type is useful for navigating between different reports or for drilling down into specific insights.

    Modal reports are often used in situations where users need to perform complex actions or view large amounts of data. For example, a Modal report might be used to display a detailed breakdown of a particular product, with the ability to drill down into individual components such as sales by region or by customer.

    All the charts have been added the parameter modal_name: Optional[str], when provided it will include the report inside the modal.

    For the specific case of the Tabs report a function has been created so that a tabs group can be included inside a Modal:

    s.plt.add_tabs_group_to_modal(
        menu_path: str,
        modal_name: str,          # the modal where the tabs group will be included
        tabs_group_name: str,     # the name of the tabs group to be included
    )

    For the customization and variation of the modal's behavior the function s.plt.update_modal must be used. The size of the modal can be changed, and the option to open the modal by default (when the user enters the path) can be achieved by setting the open_by_default: bool to True.

    s.plt.update_modal(
        menu_path: str, 
        modal_name: str, 
        open_by_default: Optional[bool],    # by default False
        width: Optional[int],               # by default 60
        height: Optional[int],              # by default 50
    )

    Another way to open the modal is by a button that triggers the event, the function to use is s.plt.modal_button. It has mostly the same parameters of the button function but is dedicated to opening a modal:

    s.plt.modal_button(
        label: str, 
        menu_path: str, 
        order: int, 
        # This modal is the one that will be opened by the button
        modal_name_to_open: str, 
        rows_size: Optional[int] = 1, 
        cols_size: int = 2, 
        align: Optional[str] = 'stretch', 
        padding: Optional[str] = None, 
        bentobox_data: Optional[Dict] = None, 
        tabs_index: Optional[Tuple[str, str]] = None,
        # This is the general modal parameter, for inclusion in a modal 
        modal_name: Optional[str] = None, 
    ):

    The next example shows how to include a normal report to a modal as well as a tabs group, and how to create a button to open that modal:

    menu_path = 'Modal Test'
    
    s.plt.update_modal(
        menu_path=menu_path, modal_name='Test modal', 
        open_by_default=True, width=90, height=90
    )
    s.plt.add_tabs_group_to_modal(
        menu_path=menu_path, modal_name='Test modal', tabs_group_name='Test'
    )
    s.plt.update_tabs_group_metadata(
        menu_path=menu_path, group_name='Test', order=1
    )
    
    modal_header = s.html_components.create_h1_title_with_modal(
        title='Modal title', subtitle='Modal subtitle', 
        background_color='var(--chart-C5)'
    )
    
    s.plt.html(
        html=modal_header, menu_path=menu_path, modal_name='Test modal', order=0
    )
    
    s.plt.html(
        html=modal_header, menu_path=menu_path, tabs_index=("Test", "Tab 1"), order=0
    )
    
    data_ = [
        {'date': dt.date(2021, 1, 1), 'x': 5, 'y': 5, 'filtA': 'A', 'filtB': 'Z', 'name': 'Ana'},
        {'date': dt.date(2021, 1, 2), 'x': 6, 'y': 5, 'filtA': 'B', 'filtB': 'Z', 'name': 'Laura'},
        {'date': dt.date(2021, 1, 3), 'x': 4, 'y': 5, 'filtA': 'A', 'filtB': 'W', 'name': 'Audrey'},
        {'date': dt.date(2021, 1, 4), 'x': 7, 'y': 5, 'filtA': 'B', 'filtB': 'W', 'name': 'Jose'},
        {'date': dt.date(2021, 1, 5), 'x': 3, 'y': 5, 'filtA': 'A', 'filtB': 'Z', 'name': 'Jorge'},
    ]
    search_columns: List[str] = ['name']
    
    s.plt.table(
        title="Test-table",
        data=data_,
        menu_path=menu_path,
        order=2,
        search_columns=search_columns,
        tabs_index=("Test", "Table"),
    )
    
    s.plt.modal_button(
        menu_path=menu_path, order=0, 
        modal_name_to_open='Test modal', label='Open modal'
    )

  • Events In Submit Form

    Now the input forms groups can trigger events when sent! The two new arguments are:

                  modal_to_open_on_submit, acivity_name_to_call_on_submit

    Using this arguments a modal can be opened or an activity can be called when the submit button is clicked.

    In the following example it is shown how to link a modal and an activity to a form:

    form_groups = {
        'Skills': [
            {
                'mapping': 'skills',
                'fieldName': 'Skills',
                'options': ['Backend', 'Frontend', 'UX/UI', 'Api Builder', 'DevOps'],
                'inputType': 'checkbox',
            },
        ]
    }
    
    s.plt.html(
        html=s.html_components.create_h1_title_with_modal(
            title='Form has been sent, congratulations!', subtitle='Modal Test',
            text_color='var(--color-white)', background_color='var(--color-primary)'
        ),
        menu_path=menu_path,
        modal_name='Congratulations modal',
        order=0
    )
    
    s.activity.create_activity(
        activity_name='test activity',
        menu_path=menu_path
    )
    
    s.plt.generate_input_form_groups(
        menu_path=menu_path, order=0,
        form_groups=form_groups,
        dynamic_sequential_show=True,
        modal_to_open_on_submit='Congratulations modal',
        acivity_name_to_call_on_submit='test activity'
    )

    The form in the dashboard appears:

    After clicking the 'send' button the modal is opened and an activity is called, in this case the activity provided doesn't have a webhook attached so it gives an error:

  • New Bentobox Charts

    Four new composite charts have been added. Each one of them uses a bentobox to group a user defined chart with a predefined component or group of components.

    • We have named the first type of charts as the Infographics Charts. These consist on joining a text bubble with a user selected chart, there are 4 options for the position of the text bubble (top, down, left, right), and it can be customized with background colors and images. It also provides the option to set an image on top of the bubble for the horizontal configuration.

      The function works like so:

      def infographics_text_bubble(
          menu_path: str, 
          title: str, 
          text: str, 
          order: int, 
          # This are the parameters that the chart function will take when executed
          chart_parameters: Dict,
          rows_size: int = 3, cols_size: int = 12, 
          # This is the funcion that will be executed passing the previous parameters,
          # by default it will use a free_echarts bar chart
          chart_function: Optional[Callable] = None,
          tabs_index: Optional[Tuple[str, str]] = None, 
          modal_name: Optional[str] = None,
          # This will be used as the background image for the bubble
          background_url: Optional[str] = None, 
          # If there is no image this color will be used as the background
          background_color: str = 'var(--background-default)',
          # Where the bubble will be located ['top', 'bottom', 'left', 'right']
          bubble_location: str = 'top', 
          # This will be the image located avobe the bubble in the horizontal configs,
          # if the string 'default' is passed it will take a default image
          image_url: Optional[str] = None, 
          # Size of the previous image
          image_size: int = 100,
      ):
      ...

      Here are some examples on how it could be used:

      • To start, the variable values that will be used are:

        menu_path = 'Infographics'
        title = 'Lorem ipsum'
        text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et " \
               "dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex" \
               " ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu" \
               " fugiat nulla pariatur. "
        data = [
            {'date': dt.date(2021, 1, 1), 'x': 5, 'y': 5},
            {'date': dt.date(2021, 1, 2), 'x': 6, 'y': 5},
            {'date': dt.date(2021, 1, 3), 'x': 4, 'y': 5},
            {'date': dt.date(2021, 1, 4), 'x': 7, 'y': 5},
            {'date': dt.date(2021, 1, 5), 'x': 3, 'y': 5},
        ]
        stacked_data = [
            {'Weekday': 'Mon', 'Email': 120, 'Union Ads': 132, 'Video Ads': 101, 'Search Engine': 134},
            {'Weekday': 'Tue', 'Email': 220, 'Union Ads': 182, 'Video Ads': 191, 'Search Engine': 234},
            {'Weekday': 'Wed', 'Email': 150, 'Union Ads': 232, 'Video Ads': 201, 'Search Engine': 154},
            {'Weekday': 'Thu', 'Email': 820, 'Union Ads': 932, 'Video Ads': 901, 'Search Engine': 934},
            {'Weekday': 'Fri', 'Email': 120, 'Union Ads': 132, 'Video Ads': 101, 'Search Engine': 134},
            {'Weekday': 'Sat', 'Email': 220, 'Union Ads': 182, 'Video Ads': 191, 'Search Engine': 234},
            {'Weekday': 'Sun', 'Email': 150, 'Union Ads': 232, 'Video Ads': 201, 'Search Engine': 154},
        ]

      • Top and bottom:

        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=4, cols_size=6,
            title=title, text=text,
            chart_function=s.plt.shimoku_gauge,
            chart_parameters=dict(
                value=random.randint(0, 100), name='Gauge', rows_size=18,
                padding='0,0,0,0'
            ),
        )
        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=6, cols_size=6, rows_size=4,
            title=title, text=text, bubble_location='bottom',
            chart_function=s.plt.stacked_barchart,
            chart_parameters=dict(
                data=stacked_data,
                x="Weekday",
                x_axis_name='weekday',
                y_axis_name='visits',
            ),
            background_color='var(--color-stripe-light)',
        )

      • Default chart and background image:

        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=8,
            title=title, text=text, bubble_location='right',
            chart_parameters=dict(
                data=data
            ),
            background_url='https://images.unsplash.com/photo-1569982175971-d92b01cf8694?ixlib=rb-4.0.3&ixid='
                           'MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80'
        )
        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=14, cols_size=6,
            title=title, text=text, bubble_location='left',
            image_url='default', image_size=60,
            background_color='var(--color-primary-light)',
            chart_parameters=dict(
                data=data,
                cols_size=10,
            )
        )
        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=16, cols_size=6, rows_size=4,
            title=title, text=text, bubble_location='right',
            image_url='default',
            chart_function=s.plt.table,
            chart_parameters=dict(
                data=data,
                cols_size=10,
            )
        )

      • Horizontal configuration with top image:

        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=14, cols_size=6,
            title=title, text=text, bubble_location='left',
            image_url='default', image_size=60,
            background_color='var(--color-primary-light)',
            chart_parameters=dict(
                data=data,
                cols_size=10,
            )
        )
        s.plt.infographics_text_bubble(
            menu_path=menu_path, order=16, cols_size=6, rows_size=4,
            title=title, text=text, bubble_location='right',
            image_url='default',
            chart_function=s.plt.table,
            chart_parameters=dict(
                data=data,
                cols_size=10,
            )
        )

    • The next entry is a drill-down chart that joins a user defined chart with a message and a modal button. The function parameters are:

      def chart_and_modal_button(
          menu_path: str, 
          order: int, 
          # This are the parameters that the chart function will take when executed
          chart_parameters: Dict,
          # This is the name of the modal that will be used by the button
          button_modal: str, 
          rows_size: int = 3,
          cols_size: int = 12, 
          # This is the funcion that will be executed passing the previous parameters,
          # by default it will use a free_echarts bar chart
          chart_function: Optional[Callable] = None,
          button_label: str = 'Read more',
          tabs_index: Optional[Tuple[str, str]] = None, 
          modal_name: Optional[str] = None,
          button_side_text: str = "Click on the button to read more about this topic.",
      ):
      ...

      An example on how to use it is:

      menu_path = 'stacked with drill-down'
      
      data = [
          {'Email': 120, 'Union Ads': 132, 'Video Ads': 101, 'Search Engine': 134, 'Weekday': 'Mon'},
          {'Email': 220, 'Union Ads': 182, 'Video Ads': 191, 'Search Engine': 234, 'Weekday': 'Tue'},
          {'Email': 150, 'Union Ads': 232, 'Video Ads': 201, 'Search Engine': 154, 'Weekday': 'Wed'},
          {'Email': 820, 'Union Ads': 932, 'Video Ads': 901, 'Search Engine': 934, 'Weekday': 'Thu'},
          {'Email': 120, 'Union Ads': 132, 'Video Ads': 101, 'Search Engine': 134, 'Weekday': 'Fri'},
          {'Email': 220, 'Union Ads': 182, 'Video Ads': 191, 'Search Engine': 234, 'Weekday': 'Sat'},
          {'Email': 150, 'Union Ads': 232, 'Video Ads': 201, 'Search Engine': 154, 'Weekday': 'Sun'},
      ]
      
      s.plt.chart_and_modal_button(
          menu_path=menu_path, order=0,
          button_modal='test modal',
          chart_function=s.plt.stacked_area_chart,
          chart_parameters=dict(
              data=data,
              x="Weekday",
              x_axis_name='Visits per weekday',
          )
      )

    • A common use case of the bentobox is to fuse indicators with other indicators and charts, as they are small reports that can easily add insight, so we have facilitated this with the chart with indicators. The function parameters are:

      def chart_and_indicators(
          menu_path: str, 
          order: int, 
          # This are the parameters that the chart function will take when executed
          chart_parameters: Dict,
          # List of groups of indicators, each one of them will be used as the input
          # of an indicators function call
          indicators_groups: List[Union[pd.DataFrame, List[Dict]]],
          # The parameters that will be passed to the indicators calls
          indicators_parameters: Dict,
          chart_rows_size: int = 3, 
          cols_size: int = 12,
          # This is the funcion that will be executed passing the previous parameters,
          # by default it will use a free_echarts bar chart
          chart_function: Optional[Callable] = None,
          tabs_index: Optional[Tuple[str, str]] = None, 
          modal_name: Optional[str] = None,
      ) -> int:

      Because it is using multiple indicators the function will return the next available order.

      The next example uses four groups of indicators and a line chart:

      menu_path = 'chart-and-indicators'
      indicator_groups = [
          [
              {
                  "footer": "-950.55",
                  "header": "Dow Jones",
                  "val": "33,195.92",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "-84.68",
                  "header": "Nasdaq",
                  "val": "10,852.16",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "-950.55",
                  "header": "Dow Jones",
                  "val": "33,195.92",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "-84.68",
                  "header": "Nasdaq",
                  "val": "10,852.16",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "-950.55",
                  "header": "Dow Jones",
                  "val": "33,195.92",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
          ],
          [
              {
                  "footer": "-950.55",
                  "header": "Dow Jones",
                  "val": "33,195.92",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "-84.68",
                  "header": "Nasdaq",
                  "val": "10,852.16",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              }
          ],
          [
              {
                  "footer": "Return of investment",
                  "header": "ROI",
                  "val": "1.5M",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "% of times the algorithm has predicted the relative position of "
                            "NY prices with respect to HK prices correctly",
                  "header": "Accuracy",
                  "val": "76.67%",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              }
          ],
          [
              {
                  "footer": "Return of investment",
                  "header": "ROI",
                  "val": "1.5M",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "% of times the algorithm has predicted the relative position of "
                            "NY prices with respect to HK prices correctly",
                  "header": "Accuracy",
                  "val": "76.67%",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              },
              {
                  "footer": "% of times the algorithm has predicted the relative position of "
                            "NY prices with respect to HK prices correctly",
                  "header": "Accuracy",
                  "val": "76.67%",
                  "alignment": "left",
                  "color": "success",
                  'variant': 'contained'
              }
          ]
      ]
      
      s.plt.chart_and_indicators(
          menu_path=menu_path, order=0,
          chart_rows_size=3, cols_size=6,
          chart_function=s.plt.line,
          chart_parameters=dict(
              data=data,
              x='date',
              y='x',
              title='Line Chart With Indicators',
          ),
          indicators_groups=indicator_groups,
          indicators_parameters=dict(
              value='val',
              header='header',
              footer='footer',
              align='alignment',
              color='color',
          )
      )

    • This last composite chart uses the previous one to create a group of indicators with a header. In this case the function definition is just a call of the previous one:

      def indicators_with_header(
          self, menu_path: str, 
          order: int, 
          # List of groups of indicators, each one of them will be used as the input
          # of an indicators function call
          indicators_groups: List[Union[pd.DataFrame, List[Dict]]],
          # The parameters that will be passed to the indicators calls
          indicators_parameters: Dict,
          # Header configuration
          title: str, 
          subtitle: str = '', 
          background_color: str = 'var(--color-primary)',
          text_color: str = 'var(--background-paper)',
          icon_url: str = 'https://uploads-ssl.webflow.com/619f9fe98661d321dc3beec7/63e3615716d4435d29e0b82c_Acurracy.svg', 
          cols_size: int = 12,
          tabs_index: Optional[Tuple[str, str]] = None, 
          modal_name: Optional[str] = None,
      ) -> int:
          return chart_and_indicators(
              self=self,
              menu_path=menu_path, order=order,
              chart_rows_size=1, cols_size=cols_size,
              tabs_index=tabs_index, modal_name=modal_name,
              chart_function=self.html,
              chart_parameters=dict(
                  html=create_h1_title_with_modal(
                      title=title, subtitle=subtitle, background_color=background_color,
                      text_color=text_color, icon_url=icon_url
                  ),
                  padding='0,0,0,0',
                  cols_size=24,
              ),
              indicators_groups=indicators_groups,
              indicators_parameters=indicators_parameters
          )

      Because it is using multiple indicators the function will return the next available order.

      The next example shows how to use the function:

      indicators_groups = [
          [
              {
                  "footer": "Total of successes predictions",
                  "header": "True",
                  "val": "154",
                  "alignment": "left",
                  "color": "success"
              },
              {
                  "footer": "Total of Failed predictions",
                  "header": "False",
                  "val": "22",
                  "alignment": "left",
                  "color": "error",
              },
              {
                  "footer": "Return of investment",
                  "header": "ROI",
                  "val": "1.5M",
                  "alignment": "left",
                  "color": "",
              },
              {
                  "footer": "% of times the algorithm has predicted the relative position of NY prices with respect to HK prices correctly",
                  "header": "Accuracy",
                  "val": "76.67%",
                  "alignment": "left",
                  "color": "success",
                  "variant": "contained"
              }
          ]
      ]
      
      s.plt.indicators_with_header(
          menu_path='test', order=0,
          title='Accuracy', subtitle='Cross-listed trading suite',
          indicators_groups=indicators_groups,
          indicators_parameters=dict(
              value='val',
              header='header',
              footer='footer',
              align='alignment',
              color='color',
              variant='variant',
              padding='0,0,0,1',
              cols_size=24,
          )
      )

  • New Free-echarts Based Charts

    Six new charts that use the s.plt.free_echarts method have bee added. Each one of them solves a concrete problem or group of problems important enough so that they have been included as library charts.

    • Scatter with effect: A scatter plot with a visual effect that highlights important points. This chart is useful for identifying patterns or trends in data and for emphasizing specific data points.

      To specify which points will have the effect the parameter effect_points must be used, it interprets each element of a list, if the elment is a list of two elements it will take that as coordinates and if the element is an integer it will take the coordinates of the point stored in the 'element' index from the source points (f.e. if element==1 the coordinates of the first point will be used).

      The input parameters are the following:

      def scatter_with_effect(
          self, data: Union[str, DataFrame, List[Dict]],
          menu_path: str, 
          # Names of columns fields that will be used for each axis
          x: str = 'x', y: str = 'y', 
          order: int, 
          rows_size: int = 3, cols_size: int = 12,
          padding: Optional[str] = None,
          title: Optional[str] = None,  # second layer
          x_axis_name: Optional[str] = None,
          y_axis_name: Optional[str] = None,
          option_modifications: Optional[Dict] = None,
          filters: Optional[Dict] = None,
          bentobox_data: Optional[Dict] = None,
          tabs_index: Optional[Tuple[str, str]] = None,
          # The points in the plane that will have the effect activated
          effect_points: Optional[List] = None,
      ):

      An example of use is:

      main_scatter_points = [
          [161.2, 51.6], [167.5, 59.0], [159.5, 49.2], [157.0, 63.0], [155.8, 53.6],
          [170.0, 59.0], [159.1, 47.6], [166.0, 69.8], [176.2, 66.8], [160.2, 75.2],
          [172.5, 55.2], [170.9, 54.2], [172.9, 62.5], [153.4, 42.0], [160.0, 50.0],
          [147.2, 49.8], [168.2, 49.2], [175.0, 73.2], [157.0, 47.8], [167.6, 68.8],
          [159.5, 50.6], [175.0, 82.5], [166.8, 57.2], [176.5, 87.8], [170.2, 72.8],
          [174.0, 54.5], [173.0, 59.8], [179.9, 67.3], [170.5, 67.8], [160.0, 47.0],
          [154.4, 46.2], [162.0, 55.0], [176.5, 83.0], [160.0, 54.4], [152.0, 45.8],
          [162.1, 53.6], [170.0, 73.2], [160.2, 52.1], [161.3, 67.9], [166.4, 56.6],
          [168.9, 62.3], [163.8, 58.5], [167.6, 54.5], [160.0, 50.2], [161.3, 60.3],
          [167.6, 58.3], [165.1, 56.2], [160.0, 50.2], [170.0, 72.9], [157.5, 59.8],
      ]
      
      dataFramed_scatter_points = [
          {'x': point[0], 'y': point[1] } for point in main_scatter_points
      ]
      
      s.plt.scatter_with_effect(
          data=dataFramed_scatter_points,
          menu_path=menu_path,
          order=0,
          x_axis_name='X axis',
          y_axis_name='Y axis',
          title='Scatter with effect',
          effect_points=[1, 2, [172.7, 105.2], [153.4, 42]]
      )

    • Line and bar charts: A combination of line and bar charts where the lines have one y-axis and the bar charts have another. This chart is useful for comparing two different sets of data that have different scales, such as sales revenue and customer satisfaction scores.

      Each axis has it's scale and it's axis name, both groups share the same space. The parameters of the function are:

      def line_and_bar_charts(self,
          data: Union[str, DataFrame, List[Dict]],
          menu_path: str, x: str = 'x', 
          bar_names: Optional[List[str]] = None, 
          line_names: Optional[List[str]] = None,
          order: Optional[int] = None, 
          rows_size: int = 3, cols_size: int = 12,
          padding: Optional[str] = None,
          title: Optional[str] = None,  # second layer
          x_axis_name: Optional[str] = None,
          bar_axis_name: Optional[str] = None,
          line_axis_name: Optional[str] = None,
          bar_suffix: Optional[str] = None,
          line_suffix: Optional[str] = None,
          option_modifications: Optional[Dict] = None,
          filters: Optional[Dict] = None,
          bentobox_data: Optional[Dict] = None,
          tabs_index: Optional[Tuple[str, str]] = None,
      ):

      An example on how to use the function is:

      menu_path: str = 'Bar and line chart'
      
      data =  [
          {'day': 'Mon', 'Evaporation': 2.0, 'Precipitation': 2.6, 'Temperature': 2.0},
          {'day': 'Tue', 'Evaporation': 4.9, 'Precipitation': 5.9, 'Temperature': 2.2},
          {'day': 'Wed', 'Evaporation': 7.0, 'Precipitation': 9.0, 'Temperature': 3.3},
          {'day': 'Thu', 'Evaporation': 23.2, 'Precipitation': 26.4, 'Temperature': 4.5},
          {'day': 'Fri', 'Evaporation': 25.6, 'Precipitation': 28.7, 'Temperature': 6.3},
          {'day': 'Sat', 'Evaporation': 76.7, 'Precipitation': 70.7, 'Temperature': 10.2},
          {'day': 'Sun', 'Evaporation': 135.6, 'Precipitation': 175.6, 'Temperature': 20.3},
      ]
      
      s.plt.line_and_bar_charts(
          data=data, menu_path=menu_path, order=0,
          x='day', 
          bar_names=['Evaporation', 'Precipitation'], 
          line_names=['Temperature'],
          title='rainfall and temperature', 
          x_axis_name='Day', 
          line_axis_name='Temperature',
          line_suffix=' °C', 
          bar_axis_name='Evaporation and precipitacion', 
          bar_suffix=' ml',
      )

    • Line with confidence area: A line chart with a shaded area that represents a confidence interval around the line. This chart is useful for showing the range of possible values around a trend line and for indicating the level of confidence in the data.

      The dataframe will have to have three value fields (top line, value line and bottom_line). The parameters of the function are:

      def line_with_confidence_area(
         data: Union[str, DataFrame, List[Dict]],
         menu_path: str, 
         # Fields for the x axis and the values
         x: str = 'x', lower: str = 'l', y: str = 'y', upper: str = 'u',
         order: Optional[int] = None, 
         rows_size: int = 3, cols_size: int = 12,
         padding: Optional[str] = None,
         title: Optional[str] = None,  # second layer
         x_axis_name: Optional[str] = None,
         y_axis_name: Optional[str] = None,
         option_modifications: Optional[Dict] = None,
         filters: Optional[Dict] = None,
         bentobox_data: Optional[Dict] = None,
         tabs_index: Optional[Tuple[str, str]] = None,
         percentages: bool = False,
      ):

      An example is:

      menu_path = 'Line with confidence area'
      
      # Download the data
      res = requests.get(url='https://echarts.apache.org/examples/data/asset/data/confidence-band.json')
      
      # Convert it to json
      data = res.json()
      
      for dat in data:
          dat['value'] = dat['value'] * 100
          dat['l'] = dat['l'] * 100
          dat['u'] = dat['u'] * 100
      
      s.plt.line_with_confidence_area(
          data=data,
          menu_path=menu_path,
          order=0,
          title='Confidence Band Chart',
          x='date', y='value', lower='l', upper='u',
          x_axis_name='Date',
          y_axis_name='Value',
          percentages=True,
      )

    • Waterfall: A chart that shows how an initial value is affected by a series of positive and negative values. This chart is useful for illustrating changes in a value over time or for identifying the components that contribute to a change.

      The input dataframe has to contain a field for positive values and a field for negative values. The balance connecting the bars can be enabled by setting the parameter show_balance to True. The parameters of the function are:

      def waterfall(
          data: Union[str, DataFrame, List[Dict]],
          menu_path: str, 
          # Fields for the x axis and the values
          xAxis: str = 'x', positive: str = 'Income', negative: str = 'Expenses',
          order: Optional[int] = None, 
          rows_size: Optional[int] = 3, cols_size: int = 12,
          padding: Optional[str] = None,
          title: Optional[str] = None,  # second layer
          x_axis_name: Optional[str] = None,
          y_axis_name: Optional[str] = None,
          option_modifications: Optional[Dict] = None,
          filters: Optional[Dict] = None,
          bentobox_data: Optional[