1
votes

Help. I'm trying to make a Gantt chart in plotly, and I'm just not seeing a way to do it. A Gantt chart is similar to a horizontal bar chart, with a 'starting' point coordinate given for each bar. So it looks like:

   XXXXX
      XXXXXX
   XXXXXXXXXXXXXXXXXXXXX
            XXXX

I can't find a way to make the 'bars' in a bar chart start at a specific X coordinate. Any tips/tricks/hints?

6
According to this chart, plotly.js doesn't do Gantt charts, but there are a few of alternatives. en.wikipedia.org/wiki/… - OneCricketeer
Bummer. I would prefer to stay with plotly.js because I am using it for other charts.... - user3089203
Before I give up.. I will try making a horizontal stacked bar, and use 'opacity: 0%' on the first data set. That should make the bars appear to float like a gantt chart. - user3089203
Sounds like a interesting idea. Make the first dataset an "offset" value - OneCricketeer

6 Answers

1
votes

Here are my results... not a perfect gantt chart, (you can not change the size of the bar, no dependencies between entries) but good enough for my purpose:

enter image description here

A code snippet to show how I did the transparent trace(s):

        // loop through all obj's to draw, for each one
        // make a transparent offset to mimic gantt chart.
        traces.push( {
           x: [ obj.totalrunTime ],
           y: [ key ],
           name: key,
           text: [ obj.totalrunTime+' '+key ], 
           orientation: 'h',
           marker: { color: obj.color },
           type: 'bar'
        });
        traces.push( {
           x: [ offset ],
           y: [ key ],
           showlegend: false,
           orientation: 'h',
           marker: { color: 'rgba(255,255,255,0)' },
           hoverinfo: "none",
           name: key,
           type: 'bar'
        });

        offset = offset + jobs[key].totalrunTime;
1
votes

Riddhiman has made a great solution for this in R. http://moderndata.plot.ly/gantt-charts-in-r-using-plotly/ . I was reluctant in the beginning because of the loop but it gives a tremendous amount of freedom.

I added a bit of extra layout for my needs:

p <- plot_ly()   
for(i in 1:(nrow(df) - 1)){
   p <- add_trace(p,
             x         = c(df$Start[i], df$Start[i] + df$Duration[i]),  # x0, x1
             y         = c(i, i),  # y0, y1
             mode      = "lines+markers+text",
             marker    = list(color  = df$color[i]
                             ,symbol = "line-ns-open"
                             ,size   = 13), #markers ensures visability
             text      = c(df$text[i],"") # adds a text string
             textposition = "middle left" #to the left of the bar
             line      = list(color  = df$color[i]
                            , width  = 20),
             showlegend = F,
             hoverinfo = "text",

             # Create custom hover text

             text      = paste0("<b>Task:</b> ",     df$Task[i],     "<br>",
                                "<b>Duration:</b> ", df$Duration[i], " days<br>",
                                "<b>Resource:</b> ", df$Resource[i]),

             evaluate  = T  # needed to avoid lazy loading
)}  
1
votes

Yes! import plotly.figure_factory as ff

ff.create_gantt(df)

Plotly has built in gantt charts. You do not need to create them from a bar chart. You can feed it a list of dictionaries or you can feed it a dataframe. If you do the latter make sure to tell the figure which column is the task, and your start and end dates. I found it much easier to use datatime and label the columns Start and Finish. this way the gantt chart will read them automatically the documentation is in the following link.

https://plot.ly/python/gantt/

1
votes

If you use plotly, use group_tasks=True if you want to want to have similar keys in one line.

0
votes

R Package vistime uses Plotly to create a Gantt chart. There is also a kind of intelligent vertical distribution of the events in the chart, such that the chart is not larger than needed.

install.packages("vistime")
library(vistime)
pres <- data.frame(Position = rep(c("President", "Vice"), each = 3),
                   Name = c("Washington", rep(c("Adams", "Jefferson"), 2), "Burr"),
                   start = c("1789-03-29", "1797-02-03", "1801-02-03"),
                   end = c("1797-02-03", "1801-02-03", "1809-02-03"),
                   color = c('#cbb69d', '#603913', '#c69c6e'),
                   fontcolor = c("black", "white", "black"))

vistime(pres, events="Position", groups="Name", title="Presidents of the USA")

example

0
votes

This is a Gantt chart with plotly

The content of "test.data":
The format is: Task\tStart\tFinish\tResource

A   2017-04-26 10:12:04 2017-04-26 10:34:18 Done
B   2017-04-26 10:54:18 2017-04-26 11:07:41 Done
C   2017-04-26 11:47:42 2017-04-26 12:25:12 Done
A   2017-04-26 12:35:12 2017-04-26 13:28:29 Done
B   2017-04-26 13:48:29 2017-04-26 14:07:50 Done
A   2017-04-26 14:37:50 2017-04-26 15:12:08 Done
B   2017-04-26 15:32:09 2017-04-26 15:44:43 Done
C   2017-04-27 07:14:46 2017-04-27 07:29:48 Done
A   2017-04-27 08:49:48 2017-04-27 09:06:07 Done
A   2017-04-27 09:38:03 2017-04-27 09:59:03 Done
C   2017-04-27 10:09:03 2017-04-27 10:27:40 Done
B   2017-04-27 11:07:40 B2017-04-27 11:23:48    Done

Here is the code:

import plotly.offline as offline
import plotly.plotly as py
import plotly.figure_factory as ff
import plotly.graph_objs as go
import plotly.io as pio
import pandas as pd
import numpy as np

filePath="test.data"

df = pd.read_table(filePath,
                   header=None,
                   usecols=[0,1,2,3],
                   sep='\t',
                   converters={1:np.datetime64, 2:np.datetime64},
                   )
df.columns = ['Task', 'Start', 'Finish', 'Resource']

colors = {'Done': 'rgb(0, 240, 0)',}

fig = ff.create_gantt(df,
                      title='My Tasks',
                      bar_width=0.1,
                      showgrid_x=False,
                      showgrid_y=False,
                      colors=colors,
                      #colors='Viridis',
                      index_col='Resource',
                      show_colorbar = True,
                      group_tasks=True,
                     )

fig['layout'].update(plot_bgcolor = 'rgba(0,0,0,250)',
                     paper_bgcolor = 'rgba(0,0,0,0)',
                     showlegend = True,
                     violinmode='overlay',
                     colorway = ['rgb(0, 150, 0)'],
                    )
pio.write_image(fig, 'testdata.pdf', format='pdf', width=1000, height=1000, scale=1)

The output:

enter image description here