Plotting function intended for an easy representation of OpenSignals acquired data.

    ----------
    Parameters
    ----------
    time : list or list of lists
        List that contains the time axis samples or a list of lists, when it is intended to present
        data in a gridplot format. When the input is a list of lists the following structure must
        be respected:
        Gridplot with N rows and M columns
        [[cell_row_0_column_0, cell_row_0_column_1, ..., cell_row_0_column_M],
         [cell_row_1_column_0, cell_row_1_column_1, ..., cell_row_1_column_M],
          ...
         [cell_row_N_column_0, cell_row_N_column_1, ..., cell_row_N_column_M]]

    data : list or list of lists
        Should have the same shape of time until the cell_row_n_column_m level. At this stage
        cell_row_n_column_m can contain a set of lists. Each one of these lists contains give
        rise to a different plot at the figure located in row n and column m of the grid structure.

    legend : list
        Input where the legend of each plot is specified. Should have the same shape of data.

    title : list
        Input where the title of each figure is specified. Should have the same shape of time.

    y_axis_label : list
        Input where the y label of each figure is specified. Should have the same shape of time.

    hor_lines : list of lists
        The parent list must have the same shape of time and each of its elements (child lists)
        must be formed by numbers defining the y axis position of the horizontal lines.

    hor_lines_leg : list of lists
        Legends of the horizontal lines (same shape of hor_lines).

    vert_lines : list of lists
        The parent list must have the same shape of time and each of its elements (child lists)
        must be formed by numbers defining the x axis position of the vertical lines.

    vert_lines_leg : list of lists
        Legends of the vertical lines (same shape of vert_lines).

    apply_opensignals_style : boolean
        If True then the OpenSignals style will be applied.


    show_plot : boolean
        If True the generated figures will be shown.

    warn_print : bool
        If True some warnings about invalid kwargs keys will be prompted.

    **kwargs : dict
        Keyword values for applying in bokeh figures, lines and gridplots.

    Returns
    -------
    out : bokeh figure or gridplot
        Object that is produced during the execution of the present function.

def _plot_future(time, data, legend=None, title=None, y_axis_label=None, hor_lines=None,
                hor_lines_leg=None, vert_lines=None, vert_lines_leg=None,
                apply_opensignals_style=True, show_plot=True, warn_print=False, **kwargs):
    """
    Plotting function intended for an easy representation of OpenSignals acquired data.

    ----------
    Parameters
    ----------
    time : list or list of lists
        List that contains the time axis samples or a list of lists, when it is intended to present
        data in a gridplot format. When the input is a list of lists the following structure must
        be respected:
        Gridplot with N rows and M columns
        [[cell_row_0_column_0, cell_row_0_column_1, ..., cell_row_0_column_M],
         [cell_row_1_column_0, cell_row_1_column_1, ..., cell_row_1_column_M],
          ...
         [cell_row_N_column_0, cell_row_N_column_1, ..., cell_row_N_column_M]]

    data : list or list of lists
        Should have the same shape of time until the cell_row_n_column_m level. At this stage
        cell_row_n_column_m can contain a set of lists. Each one of these lists contains give
        rise to a different plot at the figure located in row n and column m of the grid structure.

    legend : list
        Input where the legend of each plot is specified. Should have the same shape of data.

    title : list
        Input where the title of each figure is specified. Should have the same shape of time.

    y_axis_label : list
        Input where the y label of each figure is specified. Should have the same shape of time.

    hor_lines : list of lists
        The parent list must have the same shape of time and each of its elements (child lists)
        must be formed by numbers defining the y axis position of the horizontal lines.

    hor_lines_leg : list of lists
        Legends of the horizontal lines (same shape of hor_lines).

    vert_lines : list of lists
        The parent list must have the same shape of time and each of its elements (child lists)
        must be formed by numbers defining the x axis position of the vertical lines.

    vert_lines_leg : list of lists
        Legends of the vertical lines (same shape of vert_lines).

    apply_opensignals_style : boolean
        If True then the OpenSignals style will be applied.


    show_plot : boolean
        If True the generated figures will be shown.

    warn_print : bool
        If True some warnings about invalid kwargs keys will be prompted.

    **kwargs : dict
        Keyword values for applying in bokeh figures, lines and gridplots.

    Returns
    -------
    out : bokeh figure or gridplot
        Object that is produced during the execution of the present function.

    """

    # -------------------------------- Application of styling options -----------------------------
    if apply_opensignals_style is True:
        style_figure = {**opensignals_kwargs("figure"), **_filter_keywords(FigureOptions, kwargs,
                                                                           is_class=True,
                                                                           warn_print=warn_print)}
        style_line = {**opensignals_kwargs("line"), **_filter_keywords(Line, kwargs,
                                                                       warn_print=warn_print)}
        style_gridplot = {**opensignals_kwargs("gridplot"),
                          **_filter_keywords(gridplot, kwargs, warn_print=warn_print)}
    else:
        style_figure = _filter_keywords(FigureOptions, kwargs, is_class=True, warn_print=warn_print)
        style_line = _filter_keywords(Line, kwargs, warn_print=warn_print)
        style_gridplot = _filter_keywords(gridplot, kwargs, warn_print=warn_print)

    # ---------- Based on the input check if the output should be in the gridplot format ----------
    if len(list(numpy.shape(data))) == 3 and len(list(numpy.shape(time))) == 3:
        grid_plot = True
    elif len(list(numpy.shape(data))) == 1 and len(list(numpy.shape(time))) == 1:
        grid_plot = False
    else:
        raise RuntimeError("'time' and 'data' fields must have the same shape, which would be a "
                           "list with 1 dimension or a list of lists with 3 levels, such as [[["
                           "time_0_0, time_0,1, time_0_2], [time_1_0, time_1_1, time_1_2]]]. In the"
                           " previous example the output will be a gridplot with 2 rows and "
                           "three columns.")

    # ------------ Verification if the input arguments (title and legend) are valid ---------------
    # [legend]
    legend = _check_validity_of_inputs(data, legend, "legend", grid_plot, dimension=3)

    # [title]
    title = _check_validity_of_inputs(data, title, "title", grid_plot, dimension=2)

    # [y_axis_label]
    y_axis_label = _check_validity_of_inputs(data, y_axis_label, "y_axis_label", grid_plot,
                                             dimension=2)

    # Horizontal Lines.
    # [hor_lines]
    hor_lines = _check_validity_of_inputs(data, hor_lines, "hor_lines", grid_plot, dimension=2)
    hor_lines_leg = _check_validity_of_inputs(data, hor_lines_leg, "hor_lines_leg", grid_plot,
                                              dimension=2)

    # Vertical Lines.
    # [vert_lines]
    vert_lines = _check_validity_of_inputs(data, vert_lines, "vert_lines", grid_plot, dimension=2)
    vert_lines_leg = _check_validity_of_inputs(data, vert_lines_leg, "vert_lines_leg", grid_plot,
                                               dimension=2)

    # --------------------------------------- Plotting Stage --------------------------------------
    fig_list = []
    if grid_plot is True:
        # Each element inside "data", "time", "title", "legend" ... matrix cell must be a list.
        if all(_is_instance(list, el, condition="all", deep=True) for el in [time, data, title,
                                                                         legend, y_axis_label,
                                                                         hor_lines, vert_lines,
                                                                         hor_lines_leg,
                                                                         vert_lines_leg]):
            for row in range(0, len(data)):  # Generation of a figure per plot.
                fig_list.append([])
                for column in range(0, len(data[row])):
                    for plt in range(0, len(data[row][column])):
                        # Verification if all elements inside list are numbers.
                        if _is_instance(Number, data[row][column][plt], condition="all", deep=True) \
                                and not _is_instance(bool, data[row][column][plt], condition="any") \
                                and _is_instance(Number, time[row][column][0], condition="all") \
                                and not _is_instance(bool, time[row][column][0], condition="any"):
                            fig_list.append([])

                            # Generation of multiple figures.
                            fig_list[-1][-1].append(figure(title=title[row][column][0],
                                                           y_axis_label=y_axis_label[row]
                                                                                    [column][0],
                                                           **style_figure))

                            fig_list[-1][-1][-1].line(time[row][column][0], data[row][column][plt],
                                                      legend=legend[row][column][plt], **style_line)
                        else:
                            raise RuntimeError("At least one of the list elements, specified in "
                                               "data or time, is not numeric.")

                    # Representation of horizontal lines.
                    if hor_lines is not None:
                        for hor_line_nbr, hor_line in enumerate(hor_lines[row][column]):
                            if hor_lines_leg is not None:
                                fig_list[-1][-1][-1].line([time[row][column][0],
                                                           time[row][column][-1]],
                                                          [hor_line, hor_line],
                                                          legend=hor_lines_leg[row][hor_line_nbr],
                                                          **opensignals_kwargs("line"))
                            else:
                                fig_list[-1][-1][-1].line([time[row][column][0],
                                                           time[row][column][-1]],
                                                          [hor_line, hor_line],
                                                          **opensignals_kwargs("line"))

                    # Representation of vertical lines.
                    if vert_lines is not None:
                        for vert_line_nbr, vert_line in enumerate(vert_lines[row][column]):
                            if vert_lines_leg is not None:
                                fig_list[-1][-1][-1].line([vert_line, vert_line],
                                                          [numpy.min(data[row][column][0]),
                                                           numpy.max(data[row][column][0])],
                                                          legend=vert_lines_leg[row][vert_line_nbr],
                                                          **opensignals_kwargs("line"))
                            else:
                                fig_list[-1][-1][-1].line([vert_line, vert_line],
                                                          [numpy.min(data[row][column][0]),
                                                           numpy.max(data[row][column][0])],
                                                          **opensignals_kwargs("line"))

                    # Update of line style.
                    if apply_opensignals_style is True:
                        style_line = {**opensignals_kwargs("line"),
                                      **_filter_keywords(Line, kwargs, warn_print=warn_print)}
                    else:
                        style_line = _filter_keywords(Line, kwargs, warn_print=warn_print)

        else:
            raise RuntimeError("At least one of the list elements, specified in data, "
                               "is not a sublist.")
    else:
        # If this happen, then we receive as input a single list for time and data
        # (Single plot perspective).
        if _is_instance(Number, data, condition="all") \
                and not _is_instance(bool, data, condition="any") \
                and _is_instance(Number, time, condition="all")\
                and not _is_instance(bool, time, condition="any"):
            fig_list.append(figure(title=title, y_axis_label=y_axis_label[0], **style_figure))
            fig_list[-1].line(time, data, legend=legend, **style_line)
        else:
            raise RuntimeError("At least one of the list elements, specified in data or time, is "
                               "not numeric.")

    # Application of the OpenSignals Sytle.
    if apply_opensignals_style is True:
        opensignals_style([item for sublist in fig_list for item in sublist])

    # Show of plots.
    if grid_plot is True:
        # Generation of the gridplot.
        grid = gridplot(fig_list, **style_gridplot)

        if show_plot is True:
            show(grid)
        else:
            raise RuntimeError("The specified number of lines and columns for the grid plot is not "
                               "compatible.")

    else:
        if show_plot is True:
            show(fig_list[-1])

    return fig_list