5
$\begingroup$

How can one best create standard Gantt charts in Mathematica, where the horizontal axis is time (preferably in the Mathematica time format) and where one can include labels within each horizontal bar? TimelinePlot and standard BarChart and their relatives, which I've tried, are far too kludgy for this.

$\endgroup$
  • 1
    $\begingroup$ There is a specific example in the BarChart documentation showing you how to build a Gantt chart of employee's holidays, but I agree that there's definitely some faff involved... $\endgroup$ – Carl Lange Jun 25 '18 at 19:57
  • 2
    $\begingroup$ related: Poets of the 19th century -- also related: Timeline plotting: horizontal bars of time intervals $\endgroup$ – kglr Jun 25 '18 at 20:00
  • 2
    $\begingroup$ It would be helpful if you could add some idea of the data you're looking to place on this chart. $\endgroup$ – Carl Lange Jun 25 '18 at 20:00
3
$\begingroup$

Using the data schedule from @Edmund's answer, (1) wrapping each date range with Labeled and (2) modifying FrameTicks to add additional labels:

ranges = Map[Interval@{First@#, DatePlus @@ #} &, schedule, {2}];
boxlabels = Style[ToUpperCase@#, 12] & /@ RandomWord["Noun", Length[Join @@ schedule]];
labeling = Thread[Join @@ ranges -> boxlabels];
labeledData = Labeled[##, Before]& @@@ # & /@ (Transpose[{#, # /. labeling}] & /@ ranges);
grouplabels = StringTemplate@"GROUP `1`" /@ Range[Length@schedule];
groupsizes = Length /@ ranges;
ticklabels = StringTemplate@"PROJECT `1`" /@ Range[Length[Join @@ schedule]];
spacings = 4;

tlp = TimelinePlot[labeledData, ImageSize -> 700, LabelStyle -> 14, 
    Spacings -> spacings, Frame -> True, 
    PlotMarkers -> {Automatic, 1}, AspectRatio -> 1/GoldenRatio, 
    PlotRangePadding -> {{Scaled[.25], Automatic}, {Scaled[.02], Scaled[.05]}}, 
    PlotLayout -> "Stacked", 
    PlotStyle -> Directive[Thickness[.03], CapForm[None]], 
    PlotLegends -> SwatchLegend[grouplabels],
    GridLines -> {{AbsoluteTime@{2018, 2, 15, 8}}, None}, 
    Method -> {"GridLinesInFront" -> True}] /. Point[__] :> Nothing ;

Show[tlp, Options[tlp[[1]], FrameTicks] /. 
   {None, None} -> {MapIndexed[{ spacings #2[[1]], #} &, ticklabels], 
    MapIndexed[{spacings (Accumulate[groupsizes][[#2[[1]]]] - 
          Floor[groupsizes[[#2[[1]]]]/2]), #} &, grouplabels]}]

enter image description here

$\endgroup$
  • $\begingroup$ That is the trick for the FrameTicks for this plot. Would be good if the option worked directly in the plot ; FrameTicks->{{custom, custom}, {Automatic, Automatic}}. I tried that and it did not work. (+1) $\endgroup$ – Edmund Jun 26 '18 at 11:34
  • $\begingroup$ Thank you @Edmund. I couldn't get FrameTicks work in TimelinePlot either. Also it would have been great if PlotLabels had worked with TimelinePlot. $\endgroup$ – kglr Jun 26 '18 at 12:19
5
$\begingroup$

You may use TimelinePlot with the PlotStyle option.

For a project with schedule of start date and duration for a few teams.

SeedRandom[23032]
schedule =
 Partition[
  Transpose@{
    RandomSample[
     DateRange[DateObject@{2018, 2, 1}, DateObject@{2018, 2, 28}, "Day"], 12],
    RandomInteger[{2, 7}, 12]
    },
  3]

Then

TimelinePlot[Map[Interval@{First@#, DatePlus @@ #} &, schedule, {2}],
 PlotStyle -> Thickness@Scaled@.025,
 PlotLegends -> SwatchLegend[Automatic, StringTemplate@"Team `1`" /@ Range@4]]

Mathematica graphics

Additional formatting can be added by referring to the documentation.

Hope this helps.

$\endgroup$
  • $\begingroup$ Almost what I need. I would like to 1) label each individual bar (not just all red bars, or all green bars with a legend), and (as with all Gantt charts) label along the left side general topics such as "Project 1", "Project 2" and so on. NOT a legend. (It is sort of surprising that Mathematica does not have a Gantt chart function, since it is so widely used.) $\endgroup$ – David G. Stork Jun 26 '18 at 2:19
  • $\begingroup$ @DavidG.Stork You can use PlotLayout -> "Stacked" and Frame -> All. Then Epilog some frame labels on labels on it. I tried FrameTicks but it does not seem to like it. $\endgroup$ – Edmund Jun 26 '18 at 2:52
  • 1
    $\begingroup$ I can't seem to get your comment ideas to work, especially if the labels have different length so that mutual alignment is extremely difficult. If you could craft a single, minimal example that had all those features, I'd be grateful (and accept your solution). $\endgroup$ – David G. Stork Jun 26 '18 at 4:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.