Exemple #1
0
def create_gantt(
    df,
    colors=None,
    index_col=None,
    show_colorbar=False,
    reverse_colors=False,
    title="Gantt Chart",
    bar_width=0.2,
    showgrid_x=False,
    showgrid_y=False,
    height=600,
    width=None,
    tasks=None,
    task_names=None,
    data=None,
    group_tasks=False,
    show_hover_fill=True,
):
    """
    Returns figure for a gantt chart

    :param (array|list) df: input data for gantt chart. Must be either a
        a dataframe or a list. If dataframe, the columns must include
        'Task', 'Start' and 'Finish'. Other columns can be included and
        used for indexing. If a list, its elements must be dictionaries
        with the same required column headers: 'Task', 'Start' and
        'Finish'.
    :param (str|list|dict|tuple) colors: either a plotly scale name, an
        rgb or hex color, a color tuple or a list of colors. An rgb color
        is of the form 'rgb(x, y, z)' where x, y, z belong to the interval
        [0, 255] and a color tuple is a tuple of the form (a, b, c) where
        a, b and c belong to [0, 1]. If colors is a list, it must
        contain the valid color types aforementioned as its members.
        If a dictionary, all values of the indexing column must be keys in
        colors.
    :param (str|float) index_col: the column header (if df is a data
        frame) that will function as the indexing column. If df is a list,
        index_col must be one of the keys in all the items of df.
    :param (bool) show_colorbar: determines if colorbar will be visible.
        Only applies if values in the index column are numeric.
    :param (bool) show_hover_fill: enables/disables the hovertext for the
        filled area of the chart.
    :param (bool) reverse_colors: reverses the order of selected colors
    :param (str) title: the title of the chart
    :param (float) bar_width: the width of the horizontal bars in the plot
    :param (bool) showgrid_x: show/hide the x-axis grid
    :param (bool) showgrid_y: show/hide the y-axis grid
    :param (float) height: the height of the chart
    :param (float) width: the width of the chart

    Example 1: Simple Gantt Chart

    >>> from plotly.figure_factory import create_gantt

    >>> # Make data for chart
    >>> df = [dict(Task="Job A", Start='2009-01-01', Finish='2009-02-30'),
    ...       dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    ...       dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')]

    >>> # Create a figure
    >>> fig = create_gantt(df)
    >>> fig.show()


    Example 2: Index by Column with Numerical Entries

    >>> from plotly.figure_factory import create_gantt

    >>> # Make data for chart
    >>> df = [dict(Task="Job A", Start='2009-01-01',
    ...            Finish='2009-02-30', Complete=10),
    ...       dict(Task="Job B", Start='2009-03-05',
    ...            Finish='2009-04-15', Complete=60),
    ...       dict(Task="Job C", Start='2009-02-20',
    ...            Finish='2009-05-30', Complete=95)]

    >>> # Create a figure with Plotly colorscale
    >>> fig = create_gantt(df, colors='Blues', index_col='Complete',
    ...                    show_colorbar=True, bar_width=0.5,
    ...                    showgrid_x=True, showgrid_y=True)
    >>> fig.show()


    Example 3: Index by Column with String Entries

    >>> from plotly.figure_factory import create_gantt

    >>> # Make data for chart
    >>> df = [dict(Task="Job A", Start='2009-01-01',
    ...            Finish='2009-02-30', Resource='Apple'),
    ...       dict(Task="Job B", Start='2009-03-05',
    ...            Finish='2009-04-15', Resource='Grape'),
    ...       dict(Task="Job C", Start='2009-02-20',
    ...            Finish='2009-05-30', Resource='Banana')]

    >>> # Create a figure with Plotly colorscale
    >>> fig = create_gantt(df, colors=['rgb(200, 50, 25)', (1, 0, 1), '#6c4774'],
    ...                    index_col='Resource', reverse_colors=True,
    ...                    show_colorbar=True)
    >>> fig.show()


    Example 4: Use a dictionary for colors

    >>> from plotly.figure_factory import create_gantt
    >>> # Make data for chart
    >>> df = [dict(Task="Job A", Start='2009-01-01',
    ...            Finish='2009-02-30', Resource='Apple'),
    ...       dict(Task="Job B", Start='2009-03-05',
    ...            Finish='2009-04-15', Resource='Grape'),
    ...       dict(Task="Job C", Start='2009-02-20',
    ...            Finish='2009-05-30', Resource='Banana')]

    >>> # Make a dictionary of colors
    >>> colors = {'Apple': 'rgb(255, 0, 0)',
    ...           'Grape': 'rgb(170, 14, 200)',
    ...           'Banana': (1, 1, 0.2)}

    >>> # Create a figure with Plotly colorscale
    >>> fig = create_gantt(df, colors=colors, index_col='Resource',
    ...                    show_colorbar=True)

    >>> fig.show()

    Example 5: Use a pandas dataframe

    >>> from plotly.figure_factory import create_gantt
    >>> import pandas as pd

    >>> # Make data as a dataframe
    >>> df = pd.DataFrame([['Run', '2010-01-01', '2011-02-02', 10],
    ...                    ['Fast', '2011-01-01', '2012-06-05', 55],
    ...                    ['Eat', '2012-01-05', '2013-07-05', 94]],
    ...                   columns=['Task', 'Start', 'Finish', 'Complete'])

    >>> # Create a figure with Plotly colorscale
    >>> fig = create_gantt(df, colors='Blues', index_col='Complete',
    ...                    show_colorbar=True, bar_width=0.5,
    ...                    showgrid_x=True, showgrid_y=True)
    >>> fig.show()
    """
    # validate gantt input data
    chart = validate_gantt(df)

    if index_col:
        if index_col not in chart[0]:
            raise exceptions.PlotlyError(
                "In order to use an indexing column and assign colors to "
                "the values of the index, you must choose an actual "
                "column name in the dataframe or key if a list of "
                "dictionaries is being used.")

        # validate gantt index column
        index_list = []
        for dictionary in chart:
            index_list.append(dictionary[index_col])
        utils.validate_index(index_list)

    # Validate colors
    if isinstance(colors, dict):
        colors = clrs.validate_colors_dict(colors, "rgb")
    else:
        colors = clrs.validate_colors(colors, "rgb")

    if reverse_colors is True:
        colors.reverse()

    if not index_col:
        if isinstance(colors, dict):
            raise exceptions.PlotlyError(
                "Error. You have set colors to a dictionary but have not "
                "picked an index. An index is required if you are "
                "assigning colors to particular values in a dictioanry.")
        fig = gantt(
            chart,
            colors,
            title,
            bar_width,
            showgrid_x,
            showgrid_y,
            height,
            width,
            tasks=None,
            task_names=None,
            data=None,
            group_tasks=group_tasks,
            show_hover_fill=show_hover_fill,
            show_colorbar=show_colorbar,
        )
        return fig
    else:
        if not isinstance(colors, dict):
            fig = gantt_colorscale(
                chart,
                colors,
                title,
                index_col,
                show_colorbar,
                bar_width,
                showgrid_x,
                showgrid_y,
                height,
                width,
                tasks=None,
                task_names=None,
                data=None,
                group_tasks=group_tasks,
                show_hover_fill=show_hover_fill,
            )
            return fig
        else:
            fig = gantt_dict(
                chart,
                colors,
                title,
                index_col,
                show_colorbar,
                bar_width,
                showgrid_x,
                showgrid_y,
                height,
                width,
                tasks=None,
                task_names=None,
                data=None,
                group_tasks=group_tasks,
                show_hover_fill=show_hover_fill,
            )
            return fig
Exemple #2
0
def create_gantt(df, colors=None, index_col=None, show_colorbar=False,
                 reverse_colors=False, title='Gantt Chart', bar_width=0.2,
                 showgrid_x=False, showgrid_y=False, height=600, width=900,
                 tasks=None, task_names=None, data=None, group_tasks=False):
    """
    Returns figure for a gantt chart

    :param (array|list) df: input data for gantt chart. Must be either a
        a dataframe or a list. If dataframe, the columns must include
        'Task', 'Start' and 'Finish'. Other columns can be included and
        used for indexing. If a list, its elements must be dictionaries
        with the same required column headers: 'Task', 'Start' and
        'Finish'.
    :param (str|list|dict|tuple) colors: either a plotly scale name, an
        rgb or hex color, a color tuple or a list of colors. An rgb color
        is of the form 'rgb(x, y, z)' where x, y, z belong to the interval
        [0, 255] and a color tuple is a tuple of the form (a, b, c) where
        a, b and c belong to [0, 1]. If colors is a list, it must
        contain the valid color types aforementioned as its members.
        If a dictionary, all values of the indexing column must be keys in
        colors.
    :param (str|float) index_col: the column header (if df is a data
        frame) that will function as the indexing column. If df is a list,
        index_col must be one of the keys in all the items of df.
    :param (bool) show_colorbar: determines if colorbar will be visible.
        Only applies if values in the index column are numeric.
    :param (bool) reverse_colors: reverses the order of selected colors
    :param (str) title: the title of the chart
    :param (float) bar_width: the width of the horizontal bars in the plot
    :param (bool) showgrid_x: show/hide the x-axis grid
    :param (bool) showgrid_y: show/hide the y-axis grid
    :param (float) height: the height of the chart
    :param (float) width: the width of the chart

    Example 1: Simple Gantt Chart
    ```
    import plotly.plotly as py
    from plotly.figure_factory import create_gantt

    # Make data for chart
    df = [dict(Task="Job A", Start='2009-01-01', Finish='2009-02-30'),
          dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
          dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')]

    # Create a figure
    fig = create_gantt(df)

    # Plot the data
    py.iplot(fig, filename='Simple Gantt Chart', world_readable=True)
    ```

    Example 2: Index by Column with Numerical Entries
    ```
    import plotly.plotly as py
    from plotly.figure_factory import create_gantt

    # Make data for chart
    df = [dict(Task="Job A", Start='2009-01-01',
               Finish='2009-02-30', Complete=10),
          dict(Task="Job B", Start='2009-03-05',
               Finish='2009-04-15', Complete=60),
          dict(Task="Job C", Start='2009-02-20',
               Finish='2009-05-30', Complete=95)]

    # Create a figure with Plotly colorscale
    fig = create_gantt(df, colors='Blues', index_col='Complete',
                       show_colorbar=True, bar_width=0.5,
                       showgrid_x=True, showgrid_y=True)

    # Plot the data
    py.iplot(fig, filename='Numerical Entries', world_readable=True)
    ```

    Example 3: Index by Column with String Entries
    ```
    import plotly.plotly as py
    from plotly.figure_factory import create_gantt

    # Make data for chart
    df = [dict(Task="Job A", Start='2009-01-01',
               Finish='2009-02-30', Resource='Apple'),
          dict(Task="Job B", Start='2009-03-05',
               Finish='2009-04-15', Resource='Grape'),
          dict(Task="Job C", Start='2009-02-20',
               Finish='2009-05-30', Resource='Banana')]

    # Create a figure with Plotly colorscale
    fig = create_gantt(df, colors=['rgb(200, 50, 25)', (1, 0, 1), '#6c4774'],
                       index_col='Resource', reverse_colors=True,
                       show_colorbar=True)

    # Plot the data
    py.iplot(fig, filename='String Entries', world_readable=True)
    ```

    Example 4: Use a dictionary for colors
    ```
    import plotly.plotly as py
    from plotly.figure_factory import create_gantt

    # Make data for chart
    df = [dict(Task="Job A", Start='2009-01-01',
               Finish='2009-02-30', Resource='Apple'),
          dict(Task="Job B", Start='2009-03-05',
               Finish='2009-04-15', Resource='Grape'),
          dict(Task="Job C", Start='2009-02-20',
               Finish='2009-05-30', Resource='Banana')]

    # Make a dictionary of colors
    colors = {'Apple': 'rgb(255, 0, 0)',
              'Grape': 'rgb(170, 14, 200)',
              'Banana': (1, 1, 0.2)}

    # Create a figure with Plotly colorscale
    fig = create_gantt(df, colors=colors, index_col='Resource',
                       show_colorbar=True)

    # Plot the data
    py.iplot(fig, filename='dictioanry colors', world_readable=True)
    ```

    Example 5: Use a pandas dataframe
    ```
    import plotly.plotly as py
    from plotly.figure_factory import create_gantt

    import pandas as pd

    # Make data as a dataframe
    df = pd.DataFrame([['Run', '2010-01-01', '2011-02-02', 10],
                       ['Fast', '2011-01-01', '2012-06-05', 55],
                       ['Eat', '2012-01-05', '2013-07-05', 94]],
                      columns=['Task', 'Start', 'Finish', 'Complete'])

    # Create a figure with Plotly colorscale
    fig = create_gantt(df, colors='Blues', index_col='Complete',
                       show_colorbar=True, bar_width=0.5,
                       showgrid_x=True, showgrid_y=True)

    # Plot the data
    py.iplot(fig, filename='data with dataframe', world_readable=True)
    ```
    """
    # validate gantt input data
    chart = validate_gantt(df)

    if index_col:
        if index_col not in chart[0]:
            raise exceptions.PlotlyError(
                "In order to use an indexing column and assign colors to "
                "the values of the index, you must choose an actual "
                "column name in the dataframe or key if a list of "
                "dictionaries is being used.")

        # validate gantt index column
        index_list = []
        for dictionary in chart:
            index_list.append(dictionary[index_col])
        utils.validate_index(index_list)

    # Validate colors
    if isinstance(colors, dict):
        colors = clrs.validate_colors_dict(colors, 'rgb')
    else:
        colors = clrs.validate_colors(colors, 'rgb')

    if reverse_colors is True:
        colors.reverse()

    if not index_col:
        if isinstance(colors, dict):
            raise exceptions.PlotlyError(
                "Error. You have set colors to a dictionary but have not "
                "picked an index. An index is required if you are "
                "assigning colors to particular values in a dictioanry."
            )
        fig = gantt(
            chart, colors, title, bar_width, showgrid_x, showgrid_y,
            height, width, tasks=None, task_names=None, data=None,
            group_tasks=group_tasks
        )
        return fig
    else:
        if not isinstance(colors, dict):
            fig = gantt_colorscale(
                chart, colors, title, index_col, show_colorbar, bar_width,
                showgrid_x, showgrid_y, height, width,
                tasks=None, task_names=None, data=None, group_tasks=group_tasks
            )
            return fig
        else:
            fig = gantt_dict(
                chart, colors, title, index_col, show_colorbar, bar_width,
                showgrid_x, showgrid_y, height, width,
                tasks=None, task_names=None, data=None, group_tasks=group_tasks
            )
            return fig
def create_scatterplotmatrix(df, index=None, endpts=None, diag='scatter',
                             height=500, width=500, size=6,
                             title='Scatterplot Matrix', colormap=None,
                             colormap_type='cat', dataframe=None,
                             headers=None, index_vals=None, **kwargs):
    """
    Returns data for a scatterplot matrix.

    :param (array) df: array of the data with column headers
    :param (str) index: name of the index column in data array
    :param (list|tuple) endpts: takes an increasing sequece of numbers
        that defines intervals on the real line. They are used to group
        the entries in an index of numbers into their corresponding
        interval and therefore can be treated as categorical data
    :param (str) diag: sets the chart type for the main diagonal plots.
        The options are 'scatter', 'histogram' and 'box'.
    :param (int|float) height: sets the height of the chart
    :param (int|float) width: sets the width of the chart
    :param (float) size: sets the marker size (in px)
    :param (str) title: the title label of the scatterplot matrix
    :param (str|tuple|list|dict) colormap: either a plotly scale name,
        an rgb or hex color, a color tuple, a list of colors or a
        dictionary. An rgb color is of the form 'rgb(x, y, z)' where
        x, y and z belong to the interval [0, 255] and a color tuple is a
        tuple of the form (a, b, c) where a, b and c belong to [0, 1].
        If colormap is a list, it must contain valid color types as its
        members.
        If colormap is a dictionary, all the string entries in
        the index column must be a key in colormap. In this case, the
        colormap_type is forced to 'cat' or categorical
    :param (str) colormap_type: determines how colormap is interpreted.
        Valid choices are 'seq' (sequential) and 'cat' (categorical). If
        'seq' is selected, only the first two colors in colormap will be
        considered (when colormap is a list) and the index values will be
        linearly interpolated between those two colors. This option is
        forced if all index values are numeric.
        If 'cat' is selected, a color from colormap will be assigned to
        each category from index, including the intervals if endpts is
        being used
    :param (dict) **kwargs: a dictionary of scatterplot arguments
        The only forbidden parameters are 'size', 'color' and
        'colorscale' in 'marker'

    Example 1: Vanilla Scatterplot Matrix
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd

    # Create dataframe
    df = pd.DataFrame(np.random.randn(10, 2),
                    columns=['Column 1', 'Column 2'])

    # Create scatterplot matrix
    fig = create_scatterplotmatrix(df)

    # Plot
    py.iplot(fig, filename='Vanilla Scatterplot Matrix')
    ```

    Example 2: Indexing a Column
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd

    # Create dataframe with index
    df = pd.DataFrame(np.random.randn(10, 2),
                       columns=['A', 'B'])

    # Add another column of strings to the dataframe
    df['Fruit'] = pd.Series(['apple', 'apple', 'grape', 'apple', 'apple',
                             'grape', 'pear', 'pear', 'apple', 'pear'])

    # Create scatterplot matrix
    fig = create_scatterplotmatrix(df, index='Fruit', size=10)

    # Plot
    py.iplot(fig, filename = 'Scatterplot Matrix with Index')
    ```

    Example 3: Styling the Diagonal Subplots
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd

    # Create dataframe with index
    df = pd.DataFrame(np.random.randn(10, 4),
                       columns=['A', 'B', 'C', 'D'])

    # Add another column of strings to the dataframe
    df['Fruit'] = pd.Series(['apple', 'apple', 'grape', 'apple', 'apple',
                             'grape', 'pear', 'pear', 'apple', 'pear'])

    # Create scatterplot matrix
    fig = create_scatterplotmatrix(df, diag='box', index='Fruit', height=1000,
                                   width=1000)

    # Plot
    py.iplot(fig, filename = 'Scatterplot Matrix - Diagonal Styling')
    ```

    Example 4: Use a Theme to Style the Subplots
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd

    # Create dataframe with random data
    df = pd.DataFrame(np.random.randn(100, 3),
                       columns=['A', 'B', 'C'])

    # Create scatterplot matrix using a built-in
    # Plotly palette scale and indexing column 'A'
    fig = create_scatterplotmatrix(df, diag='histogram', index='A',
                                   colormap='Blues', height=800, width=800)

    # Plot
    py.iplot(fig, filename = 'Scatterplot Matrix - Colormap Theme')
    ```

    Example 5: Example 4 with Interval Factoring
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd

    # Create dataframe with random data
    df = pd.DataFrame(np.random.randn(100, 3),
                       columns=['A', 'B', 'C'])

    # Create scatterplot matrix using a list of 2 rgb tuples
    # and endpoints at -1, 0 and 1
    fig = create_scatterplotmatrix(df, diag='histogram', index='A',
                                   colormap=['rgb(140, 255, 50)',
                                             'rgb(170, 60, 115)', '#6c4774',
                                             (0.5, 0.1, 0.8)],
                                   endpts=[-1, 0, 1], height=800, width=800)

    # Plot
    py.iplot(fig, filename = 'Scatterplot Matrix - Intervals')
    ```

    Example 6: Using the colormap as a Dictionary
    ```
    import plotly.plotly as py
    from plotly.graph_objs import graph_objs
    from plotly.figure_factory import create_scatterplotmatrix

    import numpy as np
    import pandas as pd
    import random

    # Create dataframe with random data
    df = pd.DataFrame(np.random.randn(100, 3),
                       columns=['Column A',
                                'Column B',
                                'Column C'])

    # Add new color column to dataframe
    new_column = []
    strange_colors = ['turquoise', 'limegreen', 'goldenrod']

    for j in range(100):
        new_column.append(random.choice(strange_colors))
    df['Colors'] = pd.Series(new_column, index=df.index)

    # Create scatterplot matrix using a dictionary of hex color values
    # which correspond to actual color names in 'Colors' column
    fig = create_scatterplotmatrix(
        df, diag='box', index='Colors',
        colormap= dict(
            turquoise = '#00F5FF',
            limegreen = '#32CD32',
            goldenrod = '#DAA520'
        ),
        colormap_type='cat',
        height=800, width=800
    )

    # Plot
    py.iplot(fig, filename = 'Scatterplot Matrix - colormap dictionary ')
    ```
    """
    # TODO: protected until #282
    if dataframe is None:
        dataframe = []
    if headers is None:
        headers = []
    if index_vals is None:
        index_vals = []

    validate_scatterplotmatrix(df, index, diag, colormap_type, **kwargs)

    # Validate colormap
    if isinstance(colormap, dict):
        colormap = clrs.validate_colors_dict(colormap, 'rgb')
    elif isinstance(colormap, six.string_types) and 'rgb' not in colormap and '#' not in colormap:
        if colormap not in clrs.PLOTLY_SCALES.keys():
            raise exceptions.PlotlyError(
                "If 'colormap' is a string, it must be the name "
                "of a Plotly Colorscale. The available colorscale "
                "names are {}".format(clrs.PLOTLY_SCALES.keys())
            )
        else:
            # TODO change below to allow the correct Plotly colorscale
            colormap = clrs.colorscale_to_colors(clrs.PLOTLY_SCALES[colormap])
            # keep only first and last item - fix later
            colormap = [colormap[0]] + [colormap[-1]]
        colormap = clrs.validate_colors(colormap, 'rgb')
    else:
        colormap = clrs.validate_colors(colormap, 'rgb')


    if not index:
        for name in df:
            headers.append(name)
        for name in headers:
            dataframe.append(df[name].values.tolist())
        # Check for same data-type in df columns
        utils.validate_dataframe(dataframe)
        figure = scatterplot(dataframe, headers, diag, size, height, width,
                             title, **kwargs)
        return figure
    else:
        # Validate index selection
        if index not in df:
            raise exceptions.PlotlyError("Make sure you set the index "
                                         "input variable to one of the "
                                         "column names of your "
                                         "dataframe.")
        index_vals = df[index].values.tolist()
        for name in df:
            if name != index:
                headers.append(name)
        for name in headers:
            dataframe.append(df[name].values.tolist())

        # check for same data-type in each df column
        utils.validate_dataframe(dataframe)
        utils.validate_index(index_vals)

        # check if all colormap keys are in the index
        # if colormap is a dictionary
        if isinstance(colormap, dict):
            for key in colormap:
                if not all(index in colormap for index in index_vals):
                    raise exceptions.PlotlyError("If colormap is a "
                                                 "dictionary, all the "
                                                 "names in the index "
                                                 "must be keys.")
            figure = scatterplot_dict(
                dataframe, headers, diag, size, height, width, title,
                index, index_vals, endpts, colormap, colormap_type,
                **kwargs
            )
            return figure

        else:
            figure = scatterplot_theme(
                dataframe, headers, diag, size, height, width, title,
                index, index_vals, endpts, colormap, colormap_type,
                **kwargs
            )
            return figure
Exemple #4
0
def create_project_gantt(
    df,
    colors,
    title="Gantt Chart",
    height=None,
    width=None,
    bar_width=0.2,
    showgrid_x=False,
    showgrid_y=False,
    task_length=27,
    index_col='Resource',
    showlegend=True
):
    # validate gantt input data
    chart = validate_gantt(df)

    if index_col:
        if index_col not in chart[0]:
            raise exceptions.PlotlyError(
                "In order to use an indexing column and assign colors to "
                "the values of the index, you must choose an actual "
                "column name in the dataframe or key if a list of "
                "dictionaries is being used."
            )

        # validate gantt index column
        index_list = []
        for dictionary in chart:
            index_list.append(dictionary[index_col])
        utils.validate_index(index_list)

    # Validate colors
    colors = clrs.validate_colors_dict(colors, "rgb")

    hoverinfo = "text"

    scatter_data_template = {
        "x": [],
        "y": [],
        "mode": "none",
        "fill": "toself",
        "taskname": "",
        "percent": 0.0,
        "hoverinfo": hoverinfo,
        "legendgroup": "",
    }

    marker_data_template = {
        "x": [],
        "y": [],
        "mode": "markers",
        "text": [],
        "marker": dict(color="", size=1, opacity=0),
        "name": "",
        "showlegend": False,
    }

    # create a scatter trace for every task
    scatter_data_dict = OrderedDict()

    # create scatter traces for the start- and endpoints
    marker_data_dict = OrderedDict()

    tasks = []
    task_names = []
    index_vals = []

    # Generate list of tasks
    for index in range(len(chart)):
        task = dict(
            x0=chart[index]["Start"],
            x1=chart[index]["Finish"],
            resource=chart[index]["Resource"],
            percent = chart[index]["Percent"]
        )
        if len(chart[index]["Task"]) > task_length:
            str_break = task_length
            for i in range(task_length, 0, -1):
                if chart[index]["Task"][i] == ' ':
                    str_break = i
                    break
            name = chart[index]["Task"][0:str_break]
            name += '...'
        else:
            name = chart[index]["Task"]
        task["name"] = name

        if chart[index]['Description']:
            task["description"] = chart[index]["Description"]
        else:
            task["description"] = chart[index]["Task"]
        tasks.append(task)

        # Make sure the resource column has an associated color
        if task['resource'] not in colors:
            raise exceptions.PlotlyError(
                "If you are using colors as a dictionary, all of its "
                "keys must be all the values in the index column."
            )

    # create the list of task names
    for index in range(len(tasks)):
        tn = tasks[index]["name"]
        if tn not in task_names:
            task_names.append(tn)
            # Shorten task names if needed?

    for index in range(len(tasks)):
        # del tasks[index]["name"]

        # Separate task bars by index
        tasks[index]["y0"] = index - bar_width
        tasks[index]["y1"] = index + bar_width

        # Get the fill color from the color dictionary
        # tasks[index]["fillcolor"] = colors[chart[index][index_col]]
        # color_id = tasks[index]["fillcolor"]

        scatter_data_dict[index] = copy.deepcopy(scatter_data_template)

        color = colors[chart[index][index_col]]
        scatter_data_dict[index]["legendgroup"] = color
        scatter_data_dict[index]["fillcolor"] = color
        scatter_data_dict[index]["text"] = tasks[index]['description']
        scatter_data_dict[index]["percent"] = tasks[index]['percent']
        scatter_data_dict[index]["taskname"] = tasks[index]["name"]  # Only used for processing at the end

        # if this is the first instance of the group name appearing, make sure to put it in the legend
        group = tasks[index]['resource']
        if group not in index_vals and showlegend:
            scatter_data_dict[index]["name"] = group
            scatter_data_dict[index]["showlegend"] = True
            index_vals.append(group)
        else:
            scatter_data_dict[index]["name"] = None
            scatter_data_dict[index]["showlegend"] = False

        xs, ys = _get_corner_points(
            tasks[index]["x0"],
            tasks[index]["y0"],
            tasks[index]["x1"],
            tasks[index]["y1"],
        )

        scatter_data_dict[index]["x"] += xs
        scatter_data_dict[index]["y"] += ys

        # append dummy markers for showing start and end of interval
        marker_data_dict[index] = copy.deepcopy(marker_data_template)
        marker_data_dict[index]["marker"]["color"] = color
        marker_data_dict[index]["legendgroup"] = color

        marker_data_dict[index]["x"].append(tasks[index]["x0"])
        marker_data_dict[index]["x"].append(tasks[index]["x1"])
        marker_data_dict[index]["y"].append(index)
        marker_data_dict[index]["y"].append(index)

        marker_data_dict[index]["text"].append(tasks[index]["description"])
        marker_data_dict[index]["text"].append(tasks[index]["description"])

    layout = dict(
        title=title,
        showlegend=True,
        height=height,
        width=width,
        shapes=[],
        hovermode="closest",
        yaxis=dict(
            showgrid=showgrid_y,
            ticktext=task_names,
            tickvals=list(range(len(task_names))),
            range=[-1, len(task_names) + 1],
            autorange=False,
            zeroline=False,
        ),
        xaxis=dict(
            showgrid=showgrid_x,
            zeroline=False,
            rangeselector=dict(
                buttons=list(
                    [
                        dict(count=7, label="1w", step="day", stepmode="backward"),
                        dict(count=1, label="1m", step="month", stepmode="backward"),
                        dict(count=6, label="6m", step="month", stepmode="backward"),
                        dict(count=1, label="YTD", step="year", stepmode="todate"),
                        dict(count=1, label="1y", step="year", stepmode="backward"),
                        dict(step="all"),
                    ]
                )
            ),
            type="date",
        ),
    )

    data = [scatter_data_dict[k] for k in scatter_data_dict]
    data += [marker_data_dict[k] for k in marker_data_dict]

    percent_data = []
    rgb_pattern = re.compile('rgb\((?P<r>[0-9]+), (?P<g>[0-9]+), (?P<b>[0-9]+)\)')
    for item in data:
        if 'taskname' in item:
            entry = copy.deepcopy(item)
            match = re.match(rgb_pattern, entry['fillcolor'])
            if match:
                colors = [int(match.groupdict()['r']), int(match.groupdict()['g']), int(match.groupdict()['b'])]
                new_colors = []
                for i in range(0, len(colors)):
                    new_colors.append(int(max(0, floor((float(colors[i]) - (float(colors[i]) * 0.35))))))
                entry['fillcolor'] = 'rgb({r}, {g}, {b})'.format(r=new_colors[0], g=new_colors[1], b=new_colors[2])
            else:
                entry['fillcolor'] = '#000000'
            entry['name'] = ''
            entry['showlegend'] = False

            start = datetime.strptime(entry['x'][0], '%Y-%m-%d')
            end = datetime.strptime(entry['x'][1], '%Y-%m-%d')
            delta = (end - start).total_seconds()
            delta = int(delta * item['percent'])
            days = delta // 86400  # seconds per day
            hours = (delta - (days * 86400)) // 3600  # seconds per hour
            end = start + timedelta(days=days, hours=hours)
            end_date = str(adjust_end_date(end))

            entry['x'][1] = end_date
            entry['x'][2] = end_date
            percent_data.append(entry)
    data += percent_data

    fig = go.Figure(data=data, layout=layout)
    return fig