# DateListPlot: Highs and Lows

I have this data:

data =
{{{2015, 3, 25}, 130}, {{2015, 3, 26}, 132}, {{2015, 3, 27},
132}, {{2015, 3, 30}, 133}, {{2015, 3, 31}, 132}, {{2015, 4, 1},
131}, {{2015, 4, 2}, 131}, {{2015, 4, 3}, 131}, {{2015, 4, 6},
131}, {{2015, 4, 7}, 131}, {{2015, 4, 8}, 129}, {{2015, 4, 9},
132}, {{2015, 4, 10}, 133}, {{2015, 4, 13}, 132}, {{2015, 4, 14},
131}, {{2015, 4, 15}, 131}, {{2015, 4, 16}, 128}, {{2015, 4, 17},
125}, {{2015, 4, 20}, 127}, {{2015, 4, 21}, 127}};


I want to produce with DateListPlot an image almost like this one:

Almost? If there are more than one maxima or minima only the first point should be plotted.

In reality my data is much longer.

What could an elegant and efficient answer look like?

Perhaps a bit more elegant than Sjoerd's approach:

data = Sort @ data;   (* address Sjoerd's concern *)

pts = {
data,
MinimalBy[data, Last, 1],
MaximalBy[data, Last, 1]
};

DateListPlot[pts,
Joined    -> {True, False, False},
PlotStyle -> {Automatic, Red, Green}
]


• Certainly a highly fashionable answer :)
– eldo
Commented Apr 22, 2015 at 16:21
• Does this guarantee that you always pick the first peak if there are ties and data isn't ordered? Commented Apr 22, 2015 at 22:18
• @Sjoerd The data appeared to be ordered. Sort it if it is not. Commented Apr 22, 2015 at 22:36
• That's what I did already. The data given is just an example. Just wanted to point out that you have an implicit and unwarranted assumption in your approach. Commented Apr 22, 2015 at 22:45
• @Sjoerd I added a sort to my code. Commented Apr 22, 2015 at 23:06

Haven't aimed for efficiency or elegance but for 'straightforwardness'

data = Sort@data; (* just to make sure the dates are always sorted *)

max = Max@data[[All, 2]];
min = Min@data[[All, 2]];
maxPos = FirstPosition[data[[All, 2]], max] // First;
minPos = FirstPosition[data[[All, 2]], min] // First;

maxPlotPos = MapAt[AbsoluteTime, data[[maxPos]], 1];
minPlotPos = MapAt[AbsoluteTime, data[[minPos]], 1];

DateListPlot[data,
Epilog -> {Green, PointSize[.02], Point@maxPlotPos, Red, Point@minPlotPos}]


Lest we forget the old-fashined ways:

extremes=data[[Ordering[# data[[All,2]],1][[1]]&/@{-1,1}]];

DateListPlot[{data,##&@@(List/@extremes)},
Joined -> {True,False,False}, BaseStyle -> PointSize[Large],
PlotStyle -> {Gray,Red, Green}, PlotLegends -> {"data", "max","min"}]


Note: If data is not sorted, we need to sort it first (*thanks: @Sjoerd *):

data = data[[Ordering[data]]];
extremes = data[[Ordering[# data[[All, 2]], 1][[1]] & /@ {-1, 1}]];

• I have always liked your styles: ##&@@ is extremely nice :)
– eldo
Commented Apr 22, 2015 at 19:04
• Thank you @eldo. I think i learned it from Mr.W.
– kglr
Commented Apr 22, 2015 at 20:04
• Does this guarantee that you always pick the first peak if there are ties and data isn't ordered? Commented Apr 22, 2015 at 22:17
• Yes, I am fairly sure I am the one who infected you. :o) Commented Apr 22, 2015 at 22:37
• @SjoerdC.deVries, good point; it doesn't. So, that gives us another chance to use Ordering:)
– kglr
Commented Apr 22, 2015 at 22:52

Do you care about maxima and minima or peaks? If peaks then you could use FindPeaks but this is only available for M10+. Note also that FindPeaks only handles regularly spaced TimeSeries - hence the use of TemporalRegularity:

data = TimeSeries[{{{2015, 3, 25}, 130}, {{2015, 3, 26},
132}, {{2015, 3, 27}, 132}, {{2015, 3, 30}, 133}, {{2015, 3, 31},
132}, {{2015, 4, 1}, 131}, {{2015, 4, 2}, 131}, {{2015, 4, 3},
131}, {{2015, 4, 6}, 131}, {{2015, 4, 7}, 131}, {{2015, 4, 8},
129}, {{2015, 4, 9}, 132}, {{2015, 4, 10}, 133}, {{2015, 4, 13},
132}, {{2015, 4, 14}, 131}, {{2015, 4, 15}, 131}, {{2015, 4, 16},
128}, {{2015, 4, 17}, 125}, {{2015, 4, 20},
127}, {{2015, 4, 21}, 127}}, TemporalRegularity -> True];
DateListPlot[{data, FindPeaks[data],
TimeSeriesMap[#*-1 &, FindPeaks[TimeSeriesMap[#*-1 &, data]]]},
Joined -> {True, False, False}]


• I think this is expressly not what eldo requested but since you just introduced me to TemporalRegularity here is my +1. Commented Apr 22, 2015 at 17:00
• Right, I was not looking for peaks.+1 for the reason given by wiz. I will play with TemporalRegularity tomorrow :)
– eldo
Commented Apr 22, 2015 at 17:26
• @eldo I did push the Almost? in your question a bit far, but I decided to try and break 1000 before midnight and needed all the awkwardly placed fruit I could find. Strange to see TemporalRegularity is only mentioned three times on MMA.SE, glad to have given you something to play with though. Commented Apr 22, 2015 at 19:57
• Well, you hit it !!!
– eldo
Commented Apr 22, 2015 at 20:24