Adding custom GridLines to the "automatic" ones
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
You are asking:
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:
We start with an initial plot:
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.
System`DateListPlotDump`DateTicks
If we could identify how the automatic GridLines
are determined it would be straightforward to add the custom grid lines to the automatic ones. It seems that we can replicate the automatically generated major date ticks and hence associated grid lines using the function System`DateListPlotDump`DateTicks
in version 11 (and Graphics`DateListPlotDump`DateTicks
in version 9).
This function takes two arguments with a third optional argument:
System`DateListPlotDump`DateTicks[arg1: {mindate, maxdate}, ndivisons, labelformat]
and returns a list of (no more than ndivisions) "nice" date divisions in the range from mindate to maxdate with each tick labeled based on labelformat.
For example,
System`DateListPlotDump`DateTicks[{{2010, 1}, {2011, 3}}, 5]
{{3.47129*10^9, "Jan"}, {3.47907*10^9, "Apr"}, {3.48693*10^9, "Jul"}, {3.49488*10^9, "Oct"}, {3.50283*10^9, "Jan"}, {3.5106*10^9, "Apr"}}
The optional third argument allows formatting of date labels:
System`DateListPlotDump`DateTicks[{{2000}, {2018}}, 5, {"Year", "/", "Month"}]
{{3.15567*10^9, "2000/01"}, {3.31353*10^9, "2005/01"}, {3.47129*10^9, "2010/01"}, {3.62906*10^9, "2015/01"}, {3.78683*10^9, "2020/01"}}
The first column of the output gives the automatic grid lines on the date axis. We can append to this list additional grid lines as desired. We can replicate the major ticks on the date axis using the function
System`DateListPlotDump`DateTicks[{##}, 5, "Year"]&
in the option setting for FrameTicks
or Ticks
.
Examples:
DateListPlot[RandomReal[1, 52], {2000}, Joined -> True,
GridLines -> {(Join[System`DateListPlotDump`DateTicks[{#, #2}, 5, "Year"][[All, 1]],
{{AbsoluteTime["5 Nov 2007"], Directive[Red, Thick]},
{AbsoluteTime["5 Mar 2022"], Directive[Blue, Thickness[.007], DotDashed]}}] &), None}]
DateListPlot[RandomReal[1, 60], {2000, 1}, Joined -> True,
GridLines -> {(Join[System`DateListPlotDump`DateTicks[{#, #2}, 5, "Year"][[All, 1]],
{{AbsoluteTime["5 Nov 2001"], Directive[Red, Thick]},
{AbsoluteTime["5 Mar 2003"], Directive[Blue, Thickness[.007], DotDashed]}}] &), None}]
DateListPlot[MeanFilter[RandomReal[1, 500], 50], {2001, 5, 1},
Joined -> True, GridLinesStyle -> Green,
GridLines -> {(Join[System`DateListPlotDump`DateTicks[{#, #2}, 5, "Month"][[All, 1]],
{{AbsoluteTime["5 Nov 2001"], Directive[Red, Thick]},
{AbsoluteTime["5 Mar 2002"], Directive[Blue, Thickness[.007], DotDashed]}}] &), None}]
Post-process
Alternatively, extract the grid lines from DateListPlot
output with automatic GridLines
and use the modified list of grid lines in Show
.
dlp = DateListPlot[RandomReal[1, 60], {2000, 1}, Joined -> True,
GridLines -> {Automatic, None}];
newlines = {{AbsoluteTime["5 Nov 2001"], Directive[Red, Thick]},
{AbsoluteTime["5 Mar 2003"], Directive[Blue, Thickness[.007], DotDashed]}};
Show[dlp, GridLines -> {Join[First[GridLines /. dlp[[2]]], newlines],
Last[GridLines /. dlp[[2]]]}]