8
$\begingroup$

I am trying to plot values that occur in different days and times. I am using DateListPlot, but it plots all the values for a day in the same day. Is there a way to somehow "expand" the x-axis to show the hours?. Is there anything such as a "TimeListPlot" ? Example:

dateValues={{{2011, 2, 11, 14, 56, 0.}, 107}, {{2011, 2, 11, 14, 57, 0.}, 104}, 
{{2011, 2, 11, 14, 59, 0.}, 97}, {{2011, 2, 11, 17, 5, 0.}, 96}, 
{{2011, 2, 11, 17, 6, 0.}, 94}, {{2011, 3, 11, 9, 34, 0.}, 102}, 
{{2011, 5, 11, 12, 37, 0.}, 100}, {{2011, 5, 11, 12, 38, 0.}, 99}, 
{{2011, 7, 11, 14, 53, 0.}, 121}, {{2011, 7, 11, 14, 55, 0.}, 106}, 
{{2011, 7, 11, 14, 56, 0.}, 106}, {{2011, 7, 11, 14, 57, 0.}, 107}, 
{{2011, 7, 11, 19, 6, 0.}, 111}, {{2011, 8, 11, 18, 58, 0.}, 106}, 
{{2011, 8, 11, 19, 0, 0.}, 102}, {{2011, 8, 11, 19, 1, 0.}, 103}, 
{{2011, 9, 11, 17, 42, 0.}, 95}, {{2011, 9, 11, 17, 46, 0.}, 94}, 
{{2011, 9, 11, 19, 9, 0.}, 102}, {{2011, 10, 11, 19, 5, 0.}, 106}, 
{{2011, 10, 11, 19, 6, 0.}, 107}, {{2011, 10, 11, 19, 8, 0.}, 97}, 
{{2011, 11, 11, 11, 48, 0.}, 107}, {{2011, 11, 11, 11, 49, 0.}, 106}, 
{{2011, 11, 11, 11, 50, 0.}, 106}, {{2011, 11, 11, 11, 51, 0.}, 91}, 
{{2011, 11, 11, 11, 52, 0.}, 92}, {{2011, 11, 11, 11, 53, 0.}, 123}, 
{{2011, 11, 11, 11, 54, 0.}, 120}, {{2011, 11, 11, 11, 55, 0.}, 98}}

Then, if you plot it:

DateListPlot[dateValues]

Mathematica graphics

You get all the first 5 values in the same column.

Lets try to plot more than one value in the "relaxed" axis that @doctor_image created:

dateValues2={{{2011, 2, 11, 14, 56, 0.}, 107, 60, 51}, {{2011, 2, 11, 14, 57, 0.}, 104, 60, 50}, 
{{2011, 2, 11, 14, 59, 0.}, 97, 60, 46}, {{2011, 2, 11, 17, 5, 0.}, 96, 65, 49}, 
{{2011, 2, 11, 17, 6, 0.}, 94, 66, 71}, {{2011, 3, 11, 9, 34, 0.}, 102, 66, 51}, 
{{2011, 5, 11, 12, 37, 0.}, 100, 65, 59}, {{2011, 5, 11, 12, 38, 0.}, 99, 66, 53}, 
{{2011, 7, 11, 14, 53, 0.}, 121, 83, 44}, {{2011, 7, 11, 14, 55, 0.}, 106, 59, 37}, 
{{2011, 7, 11, 14, 56, 0.}, 106, 62, 35}, {{2011, 7, 11, 14, 57, 0.}, 107, 69, 50}, 
{{2011, 7, 11, 19, 6, 0.}, 111, 66, 49}, {{2011, 8, 11, 18, 58, 0.}, 106, 67, 55}, 
{{2011, 8, 11, 19, 0, 0.}, 102, 64, 50}, {{2011, 8, 11, 19, 1, 0.}, 103, 68, 53}, 
{{2011, 9, 11, 17, 42, 0.}, 95, 60, 47}, {{2011, 9, 11, 17, 46, 0.}, 94, 58, 43},    
{{2011, 9, 11, 19, 9, 0.}, 102, 61, 54}, {{2011, 10, 11, 19, 5, 0.}, 106, 69, 49}, 
{{2011, 10, 11, 19, 6, 0.}, 107, 68, 51}, {{2011, 10, 11, 19, 8, 0.}, 97, 60, 47}, 
{{2011, 11, 11, 11, 48, 0.}, 107, 68, 53}, {{2011, 11, 11, 11, 49, 0.}, 106, 66, 47}, 
{{2011, 11, 11, 11, 50, 0.}, 106, 64, 49}, {{2011, 11, 11, 11, 51, 0.}, 91, 71, 77}, 
{{2011, 11, 11, 11, 52, 0.}, 92, 72, 82}, {{2011, 11, 11, 11, 53, 0.}, 123, 85, 57}, 
{{2011, 11, 11, 11, 54, 0.}, 120, 82, 62}, {{2011, 11, 11, 11, 55, 0.}, 98, 81, 77}}

I managed to plot them on a regular graphics, but can not use the "relaxed axis":

With[{labels = 
Rotate[DateString@#, (3 \[Pi])/2] & /@ dateValues2[[All, 1]]}, 
ListPlot[{dateValues2[[All, 2]], dateValues2[[All, 3]], 
dateValues2[[All, 4]]}, 
Ticks -> {Transpose[{Range@Length@labels, labels}], Automatic}, 
Filling -> {1 -> {2}}, Joined -> {False, False, True}]]

Blood pressure and pulse plot

It is a visual way to plot blood pressure and pulse. Any suggestion on how to use the "relaxed" axis?

$\endgroup$
0

2 Answers 2

10
$\begingroup$

This will plot the date values regularly spaced apart, with the dates as rotated string labels on the x-axis, in a fashion similar to that you describe in Excel.

With[{labels = Rotate[DateString@#, (3 \[Pi])/2] & /@ dateValues[[All, 1]]}, 
 ListPlot[dateValues[[All, 2]], 
  Ticks -> {Transpose[{Range@Length@labels, labels}], Automatic},Filling->Axis]]

Mathematica graphics

With a little more fiddling, it is possible to get something that tries to reflect the proper flow of the time line. Though it constrains points to have a minimum spacing between them.

(* Ease points that are close to one another apart, 
by minimum separation MinSeparation * ( Max-Min ) of data  *)

Options[Relax] = {MinSeparation -> 0.02};
Relax[data_, OptionsPattern[]] := 
 With[{sep = OptionValue@MinSeparation (Max@data - Min@data)}, 
  Flatten[{First@data, First@data + Accumulate[If[# < sep, sep, #] & /@ Differences@data]}]]

Plot the values with date labels:

With[{labels = Rotate[DateString@#, (3 \[Pi])/2] & /@ dateValues[[All, 1]], 
  softCoords = Relax[AbsoluteTime /@ dateValues[[All, 1]]]}, 
 ListPlot[{softCoords, dateValues[[All, 2]]}\[Transpose], 
  Ticks -> {{softCoords, labels}\[Transpose], Automatic}, 
  Filling -> Axis, AxesOrigin -> {First@softCoords - 10^6, 80}]]

Mathematica graphics

For your revised data here is the Plotting code:

With[{labels = 
   Rotate[DateString@#, (3 \[Pi])/2] & /@ dateValues2[[All, 1]], 
  softCoords = Relax[AbsoluteTime /@ dateValues2[[All, 1]]]}, 
 ListPlot[{
 {softCoords, dateValues2[[All, 2]]}\[Transpose], 
 {softCoords, dateValues2[[All, 3]]}\[Transpose], 
 {softCoords, dateValues2[[All, 4]]}\[Transpose]}, 
  Ticks -> {{softCoords, labels}\[Transpose], Automatic}, 
  AxesOrigin -> {First@softCoords - 10^6, 0}, 
  Joined -> {False, False, True}, Filling -> {1 -> {2}}]]

Giving a plot like this:

Mathematica graphics

Relax generates a set of new coordinates for the data, which have been eased apart.

These new coordinates then form the basis of the Relaxed plot constructed using ListPlot.

Each set of data associated with a date can then be fed into ListPlot as a list of {softcoordinate,value } pairs ( i.e. {AbsoluteTime, value } ). This is achieved by the idiom:

{softCoords, dateValues2[[All, 2]]}\[Transpose]

$\endgroup$
11
  • 2
    $\begingroup$ @Szabolcs Thanks for the very useful "Upload To Se" palette. $\endgroup$ Apr 28, 2012 at 8:53
  • $\begingroup$ thank you, this is exactly what I was looking for. $\endgroup$
    – ninescita
    Apr 30, 2012 at 21:57
  • $\begingroup$ Glad we could help :) $\endgroup$ Apr 30, 2012 at 22:31
  • $\begingroup$ One last question, imagine you want to plot more than one value in this same graphic. I am plotting blood preassure and pulse, so I joined sytolic and diastolic preassure with a vertical line, and joined the pulse meters. But I can not manage to include it in the "relaxed" axis. Any suggestions?. Thank you @Szabolcs also for your valuable help. Please find the code in the next comment: $\endgroup$
    – ninescita
    May 2, 2012 at 19:30
  • $\begingroup$ mmmm..., I do not know how to paste the code... I try via a reply, sorry for being so nerd :-( $\endgroup$
    – ninescita
    May 2, 2012 at 19:40
6
$\begingroup$

DateListPlot does handle hours and minutes correctly. However, your data spans many months (from February to November), so at this scale a difference of a single hour is simply not visible.

Also, I have the impression that in your data the month and day may be exchanged. You have the 11th of each month. Note: first value is year, second is month, third is day.

$\endgroup$
6
  • $\begingroup$ Thanks, yes the values are exchanged (Spanish date formats...), let me try again. $\endgroup$
    – ninescita
    Apr 27, 2012 at 11:49
  • $\begingroup$ Did not work, I exchanged the values, but the data is still "stacked" in the same day. dateValues2 = dateValues /. {{a_, b_, c_, d_, e_, f_}, g_} -> {{a, c, b, d, e, f}, g} $\endgroup$
    – ninescita
    Apr 27, 2012 at 11:53
  • 1
    $\begingroup$ As I said, the reason is the scale of the data. If you look closely, they're not stacked. But given the tiny differences in times, they appear to be. $\endgroup$
    – Szabolcs
    Apr 27, 2012 at 12:10
  • $\begingroup$ You are right, thank you. And by any chance do you know how to change the scale?. I could ignore the scale if I could plot date and time in the x axis.... $\endgroup$
    – ninescita
    Apr 27, 2012 at 12:21
  • $\begingroup$ You can use the PlotRange option to restrict the plot range. Of course in this case some of the data points will be off the graph, but the difference between times will be visible. $\endgroup$
    – Szabolcs
    Apr 27, 2012 at 12:49

Your Answer

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

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