Reputation: 65
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?
Upvotes: 1
Views: 9314
Reputation: 503
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:
Upvotes: 1
Reputation: 6165
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")
Upvotes: 0
Reputation: 21
If you use plotly, use group_tasks=True
if you want to want to have similar keys in one line.
Upvotes: 1
Reputation: 2298
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.
Upvotes: 2
Reputation: 321
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
)}
Upvotes: 1
Reputation: 65
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:
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;
Upvotes: 1