Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I've made a gauge like instrument that will get used to prompt someone to maintain rhythmic breathing patterns during heart/brain coherence training.

Manipulate[ListLinePlot[(Table[#, {10}] & /@ Range[10]) a,
  PlotRange -> {{0, 11}, {0, 10}},
  AspectRatio -> 3.5,
  ImageSize -> 100,
  PlotStyle -> LightGray,
  Axes -> {False, True},
  Filling -> Axis,
  FillingStyle -> LightGreen,
  Frame -> True,
  FrameTicks -> {{True, True}, {None, None}}
  ], {a, 0, 1},
 Paneled -> False,
 ControlType -> None,
 AutorunSequencing -> 3
 ]

Note that after executing the code you'll need to click on the + in the upper right corner of the output to get to Autorun, which will get you the following:

enter image description here

This nicely runs up and down, but now I'd like the ability to set four things programatically.

  • A default speed at which the gauge will run up (e.g., 5 seconds);
  • A default speed at which the gauge will run down (e.g., 4 seconds);
  • A timed delay at the bottom (e.g., 2 seconds, which I currently kind of hack with AutorunSequencing -> 3); and
  • A timed delay at the top.

I had originally tried doing this with Animate[], but it seemed to have too many limitations.

Maybe the same holds for Manipulate[] and I have to go to basics with Dynamic[].

I thought it worth asking. Any suggestions welcomed.

share|improve this question
    
There are informations about this in "manipulate secret revealed", version 2007 (library.wolfram.com/infocenter/Conferences/7001), page 12. There is something better elsewhere, but I can't find it. –  andre Mar 13 '13 at 23:41
add comment

2 Answers

up vote 3 down vote accepted

Sorry, I missed the pause at the top. Corrected:

breather[up_, p1_, down_, p2_] := 
 With[{f = Interpolation[{Accumulate@{0, up, p1, down, p2}, {0, 1, 1, 0, 0}}\[Transpose], 
     InterpolationOrder -> 1]}, 
  Animate[ListLinePlot[(Table[#, {10}] & /@ Range[10]) f[a], 
    PlotRange -> {{0, 11}, {0, 10}}, AspectRatio -> 3.5, ImageSize -> 100, 
    PlotStyle -> LightGray, Axes -> {False, True}, Filling -> Axis, 
    FillingStyle -> LightGreen, Frame -> True, 
    FrameTicks -> {{True, True}, {None, None}}], {a, 0, up + p1 + down + p2}, 
   AnimationRate -> 1]
]

Usage is simply times in seconds for up, pause1, down, and pause2:

breather[3, 0.7, 2, 2]

Mathematica graphics

share|improve this answer
    
You got this one by a nose;-) With two solutions, both relying on Animate, your use of With seems just a tiny bit more elegant and direct. Many thanks. –  Jagra Mar 14 '13 at 12:29
    
@Jagra Thank you. I like the fact that this method is easily extendable. You could change it to accept two vectors, one a list of times and the other a list of the positions. You could also experiment with different interpolation orders or methods, which might be more lifelike. –  Mr.Wizard Mar 14 '13 at 14:00
    
+1; I agree that this is a nicer solution. Good reminder of the usefulness/adaptability of InterpolatingFunction objects. –  Eric Thewalt Mar 14 '13 at 22:58
add comment

We can do this using Animate[] by manually constructing the list of values that a takes, and setting AnimationRate to give the correct times, in seconds:

rhythmicBreath[tUp_, tDown_, tTop_, tBottom_] := 
 Animate[ListLinePlot[(Table[#, {10}] & /@ Range[10]) a, 
   PlotRange -> {{0, 11}, {0, 10}}, AspectRatio -> 3.5, 
   ImageSize -> 100, PlotStyle -> LightGray, Axes -> {False, True}, 
   Filling -> Axis, FillingStyle -> LightGreen, Frame -> True, 
   FrameTicks -> {{True, True}, {None, None}}], 
   {a, Join @@ {Range[0, 1, .05/tUp], ConstantArray[1, 20 tTop // Round], 
     Reverse@Range[0, 1, .05/tDown], ConstantArray[0, 20 tBottom // Round]}},
   Paneled -> False, AnimationRate -> 20]

rhythmicBreath[5, 4, 2, 2] produces an autorunning graphic with a visible control: Mathematica graphics

In version 8, the animation slider pauses during the "holds" (repeated ones or zeros in the list of a values). There are obvious hacky ways around this, but maybe someone has a nice solution.

share|improve this answer
    
Thanks for an interesting solution +1 from me. –  Jagra Mar 14 '13 at 12:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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