# How to rotate TickMarks in DateListPlot?

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

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

-
See my somewhat relevant question also: mathematica.stackexchange.com/questions/2652/… –  s0rce Jul 23 '12 at 14:29

Perhaps something like this?

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

p = DateListPlot[data];

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


If one prefers not to use Show then:

p /. x : (FrameTicks -> _) :> (x /. s_String :> Rotate[s, 90 Degree])

-
Outstanding. Is there a way to inline it or is the call to Show necessary? –  alancalvitti Jul 16 '12 at 22:08
@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. –  Mr.Wizard Jul 16 '12 at 22:18

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


-
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. –  alancalvitti Jul 16 '12 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}};

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


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

-
To be fair, op didn't have code in the question until later well after both answers were given and one accepted... :) –  rm -rf Jul 17 '12 at 5:42
@R.M Ah, I see - one of those telepathic answers where you had to divine the question first. –  Jens Jul 17 '12 at 6:12
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. –  alancalvitti Jul 17 '12 at 17:45
@alancalvitti It's not a contest, so I guess winning is even harder. That just adds to the challenge. –  Jens Jul 17 '12 at 21:19