# Adding custom GridLines to the “automatic” ones

I need to add custom (vertical) grid lines to a plot (to a DateListPlot, to be precise). I know there is the option of GridLines -> {xgrid, ygrid}. However, this removes the automatic grid lines which I would like to keep.

Is there a simple option to add additional grid lines to the automatic ones? Thank you!

Update: Added a minimal working example.

Take the following DateListPlot

DateListPlot[RandomReal[1, 20], {2000}, Joined -> True]


It automatically includes vertical grid lines for each year in grey, which I would like to keep. But let's say I'd like to add a grid line for Guy Fawkes Day 2007, e.g. because I need to later label the event in the plot. I could write

 DateListPlot[RandomReal[1, 20], {2000}, Joined -> True,
GridLines -> {{"5 Nov 2007"}, None}]


but this removes the yearly lines. So I was wondering whether it is possible to add the custom grid lines to the automatic ones rather than to overwrite the latter.

Of course, I could manually re-add the annual grid lines, but I hope to avoid this solution because the plots will have different date ranges so I do not always know for which years I'd need to include the lines.

-
If you add code for a small working example, more people will likely be inclined to help you. –  Ajasja May 17 '13 at 9:37
I've included an example. –  Bernd May 17 '13 at 9:50
At worst, one could fall back on Epilog and manually add markers for "special" dates (that is, explicitly construct a vertical Line[]). –  Ｊ. Ｍ. May 17 '13 at 9:55
@J.M. Yes, but then I would need to know the y coordinates of the line (i.e. upper and lower bounds), which depends on the range of the data to be plotted. Else, the line will be taller or shorter than the grid itself. –  Bernd May 17 '13 at 9:58

Not sure why J.M.'s comment doesn't meet your requirements:

DateListPlot[
RandomReal[1, 20], {2000},
Joined -> True,
PlotRange -> All,
GridLines -> {Automatic, None},
Epilog -> {Directive[Thick, Magenta],
Line[
{Scaled[{0, -1}, {{2010, 1, 15}, 0}],
Scaled[{0, 1}, {{2010, 1, 15}, 0}]
}]}]


This incorporates Scaled, acknowledging J.M.'s additional comments below as well.

Edit: To add multiple such lines to a graph, the following function takes the dates as arguments and displays them accordingly:

specialdates[dates__] := DateListPlot[
RandomReal[1, 20], {2000}, Joined -> True, PlotRange -> All,
Prolog -> {Directive[Orange], Line[
{Scaled[{0, -1}, {DateString[{#, {"Day", "Month", "Year"}}], 0}],
Scaled[{0, 1}, {DateString[{#, {"Day", "Month", "Year"}}], 0}]}]
& /@ {dates}}]


So that

specialdates["05.11.2005", "04.07.2007", "14.07.2011", "12.10.2017"]


yields

-
It might be more useful to use Scaled[] for offsetting in the vertical direction. If you use Epilog -> {Directive[Thick, Magenta], Line[{Scaled[{0, -1}, {{2010, 1, 15}, 0}], Scaled[{0, 1}, {{2010, 1, 15}, 0}]}]}, you'll find that even if you change the PlotRange, the vertical magenta line will always hit the horizontal boundaries. –  Ｊ. Ｍ. May 17 '13 at 10:14
@J.M. Good plan; I haven't learnt about Scaled yet. (It's the scaling/offset/positioning stuff in Mathematica that still confuses me...) –  cormullion May 17 '13 at 10:25
Here, the notation is not too hard to parse. Scaled[{0, h}, start] corresponds to a scaled vertical offset from the point start; positive values of h go up, and negative values of h go down. h == -1 is the bottommost position, and h == 1 is the topmost. The situation is similar for horizontal offsetting, with Scaled[{h, 0}, start]. –  Ｊ. Ｍ. May 17 '13 at 10:48
Ok, the combination of Epilog and Scaled indeed seems to be the most reasonable solution. Thank you all! –  Bernd May 17 '13 at 11:26
@Bernd Actually it should probably be Prolog instead of Epilog –  Ajasja May 17 '13 at 13:02

Is there a simple option to add additional grid lines to the automatic ones? Thank you!

Well, I couldn't think of one, but out of curiosity I tried another approach (different to the Epilog I'd also rather choose). It seems to work pretty ok, so I figured I might share. As the other answer is much more versatile, I didn't spend too much time tidying up my code, if you are interested in more details let me know.

Consider the DateListPlot you mentioned:

dlp = DateListPlot[RandomReal[1, 20], {2000}, Joined -> True,
GridLines -> {Automatic, None}];


Now, the idea is to just add the desired additional gridlines to dlp directly. Using dlp//FullForm we can easily identify the GridLines and can thus set up the following ReplacemeAll:

addVertGridLine[plot_,dates_List] :=
(plot /.
# ->
Insert[#,
Unevaluated[
Sequence @@ ({AbsoluteTime[#[[1]]], #[[2]]} & /@ dates)], {2,1,-1}]) &@
Cases[plot, x_Rule /; x[[1]] == GridLines, Infinity][[1]]


in words: I use Cases to find the GridLines and then I insert the (unevaluated) Sequence of dates in that list, at the right spot (using AbsoluteTime to make it a bit more user friendly). The setup expects the user to enter a list of date/style lists (in order to make it possible to add many gridlines in one go).

An example will certainly help:

dlp = DateListPlot[RandomReal[1, 20], {2000}, Joined -> True, GridLines -> {Automatic, None}]


and let's add few Guy Fawkes days:

addVertGridLine[dlp,
{{"5 Nov 2005", Directive[Red, Thick]},
{"5 Nov 2008", GrayLevel[0.8]}
{"5 Nov 2012", Directive[Blue, Dashed]},
{"5 Nov 2014", Green}}]
`

showing various formatting.

I hope this helps.

-