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
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
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