Is there a way to rotate TickMarks in DateListPlot to avoid overlap, eg:

enter image description here

Part of the code used to generate this is:

TimelineGr[file_] := 
 DateListPlot[{{First[#], 1}, {Last[#], Length@#}} &@
   Sort@Flatten[ Last /@ I2B2[file, dateIntervals], 1], 
  Epilog -> ({Text[First@#, {First@Last@#, First@#2}, {1, 0}], Blue, 
       Rectangle[{First@Last@#, First@#2}, {Last@Last@#, 
         First@#2 + 0.1}]} &~MapIndexed ~ I2B2[file, dateIntervals]),
  PlotRange -> All, AspectRatio -> 1/4, ImageSize -> 800, 
  DateTicksFormat -> {"Year", "/", "Month", "/", "Day"}, 
  FrameTicks -> {{Automatic, Automatic}, { 
     First[Last[#]] & /@ I2B2[file, dateIntervals], Automatic}}, 
  PlotLabel -> file <> ".xml"

(Note, this includes custom functions)

If not, this is just another example of why it's almost always better to write visualization from the bottom-up


4 Answers 4


Perhaps something like this?

data = {{{2006, 10, 1}, 10}, {{2006, 10, 15}, 12},
        {{2006, 10, 30}, 15}, {{2006, 11, 20}, 20}};

p = DateListPlot[data];

  Options[p, FrameTicks] /. s_String :> Rotate[s, 90 Degree]

Mathematica graphics

If one prefers not to use Show then:

p /. x : (FrameTicks -> _) :> (x /. s_String :> Rotate[s, 90 Degree])
  • $\begingroup$ Outstanding. Is there a way to inline it or is the call to Show necessary? $\endgroup$ Jul 16, 2012 at 22:08
  • $\begingroup$ @alancalvitti when you say "inline" do you mean do this entirely from within DateListPlot with options? If so, not that I know of. Otherwise I'm not sure what you mean. You could do it with only /. and not Show but I think it will be less clean; nevertheless if you want that I'll post it. $\endgroup$
    – Mr.Wizard
    Jul 16, 2012 at 22:18
  • 1
    $\begingroup$ @Mr.Wizard, This is not working in the current MMA version. V10.3 $\endgroup$ Dec 9, 2015 at 16:17

Mr.Wizard has shown you how to rotate the labels. Sometimes, it might also be useful to simply offset alternate labels so that it doesn't clash and is more readable. For example:

Block[{i = 1},
    DateListPlot[data, DateTicksFormat -> {"Day", "/", "Month", "/", "Year"}] /. 
        s_String :> If[s =!= "" && OddQ[i], i += 1; s, i += 1; Column[{"", s}]]

enter image description here

  • $\begingroup$ Very nice. The next level is to spread out TickMarks when they are not regularly spaced and cluster in time. The graphic I included in my post shows a simple example but it gets a lot worse with TimeML data where some dates are days others months others years and all should be covered in a single timeline. $\endgroup$ Jul 16, 2012 at 23:22

Given that the original question already uses so many different options, I think the most obvious answer is the one that makes use of exactly these existing options. This requires no post-processing whatsoever. By post-processing, I mean the replacement rules s_String :> ...

data = {{{2006, 10, 1}, 10}, {{2006, 10, 25}, 12}, {{2006, 10, 30}, 
    15}, {{2006, 11, 20}, 20}};

 FrameTicks -> 
   {Automatic, None},
         DateString[#, {"Year", "/", "Month", "/", "Day"}],
         90 Degree]
        , RoundingRadius -> 5,
        FrameStyle -> None,
        Background -> LightOrange
       {0, .01}
       } &,
     data[[All, 1]]


All the heavy lifting is done by the FrameTicks option. The list data contains all the information necessary to create the positions and text for the tick labels, more precisely we need only the first entries: data[[All, 1]].

The Map command uses each date entry in data[[All, 1]] to create a list that identifies a tick mark with a position and label. The label part is rotated by 90 degrees - I also chose to add a rounded rectangle background using Framed, and make the tick mark extend outside the frame toward the label, by using a tuple {0, .01} for the tick length specification.

This approach has some potential advantages, other than making full use of the existing options: in particular, making pattern replacements in a post-processing step may require more carefully crafted conditions (instead of s_String) if some of the labels on the vertical axis happen to be customized with strings too (e.g., instead of purely numbers from 0 to 20, you could have one special tick labeled by a word like "special value" - then that word would unintentionally get rotated along with the date labels).

See also this answer to a closely related question, "Centering date labels over the year in a DateListPlot"

  • $\begingroup$ To be fair, op didn't have code in the question until later well after both answers were given and one accepted... :) $\endgroup$
    – rm -rf
    Jul 17, 2012 at 5:42
  • $\begingroup$ @R.M Ah, I see - one of those telepathic answers where you had to divine the question first. $\endgroup$
    – Jens
    Jul 17, 2012 at 6:12
  • $\begingroup$ This isn't a contest. But I'm glad SE exists - it's the best thing since ice cubes. Particuarly since WRI charges $300/hr for professional services. $\endgroup$ Jul 17, 2012 at 17:45
  • $\begingroup$ @alancalvitti It's not a contest, so I guess winning is even harder. That just adds to the challenge. $\endgroup$
    – Jens
    Jul 17, 2012 at 21:19

An answer in the same vein as @Mr.Wizard's, but that works in more recent versions of Mathematica:

data = {{{2006, 10, 1}, 10}, {{2006, 10, 15}, 12}, {{2006, 10, 30}, 15}, {{2006, 11, 20}, 20}};

dlp = DateListPlot[data];

(*get x plotrange*)
xpr = First[PlotRange /. Options[dlp, PlotRange]];

(*get the frameticks that DateListPlot uses by default from the internal function*)
ticks = (Charting`DateTicksFunction[Automatic, DateTicksFormat -> {Automatic}] @@ xpr);

(* manually adjust styling (adding rotation) for ticks gathered above *)
rotatedTicks = Replace[
     {x_, Style[y_String, specs__], z_List, d_Directive} :> {x, Style[Rotate[y, 80 Degree], specs], z, d}, 

(*add our "custom" ticks back into the plot*)
     FrameTicks -> {{Automatic, Automatic}, {rotatedTicks, Automatic}}

rotated ticks pic

This gets the ticks manually from the internal Charting`DateTicksFunction function, and then post-processes them and plugs them back into the graphics object.

YMMV, and this uses internal functionality that may change in a future release.

  • $\begingroup$ Rotate rotates the text around its center. If you add GridLines -> Automatic and change the rotation angle to 45 the tick labels look offset from the grid. Is there a way to rotate so that the end of the label lines up with the grid? I tried setting the third argument to Rotate to {Right, Center} but that seemed to have no effect. $\endgroup$ Feb 5, 2021 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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