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.

Is it possible to make $y_{max}$ of Slider[y, {$y_{min}$,$y_{max}$}] depend on another control?

For example, I have three variables (Time, Type1, Type2). I want a drop down box for the user to select which type to plot. And I want the user to have the ability to scale up and down the y value (however the maximum y value should depend on the level chosen, 150000 for Type1 and 1 for Type2).

mySubset = {{0.`, 0.`, 0.`}, {60.`, 78069.`, 0.52046`}, {120.`, 
81417.`, 0.54278`}, {180.`, 84765.`, 0.5651`}, {240.`, 88113.`, 
0.58742`}, {300.`, 91461.`, 0.60974`}, {360.`, 94809.`, 
0.63206`}, {420.`, 98157.`, 0.65438`}, {480.`, 101505.`, 
0.6767`}, {540.`, 104853.`, 0.69902`}, {600.`, 108201.`, 
0.72134`}, {660.`, 111549.`, 0.74366`}, {720.`, 114897.`, 
0.76598`}, {780.`, 118245.`, 0.7883`}, {840.`, 121593.`, 
0.81062`}, {900.`, 124941.`, 0.83294`}, {960.`, 128289.`, 
0.85526`}, {1020.`, 131637.`, 0.87758`}, {1080.`, 134985.`, 
0.8999`}, {1140.`, 138333.`, 0.92222`}};

yTypes = {"Type1", "Type2"}
yMax = {0., 150000., 1.}
Manipulate[
 Module[{week, y},
  yColumn = (Position[yTypes, yChosen][[1]])[[1]] + 1;
  y = Part[mySubset, All, yColumn];
  week = Part[mySubset, All, 1]/10080;
  ListPlot[Transpose[{week, y}], Joined -> True, 
   PlotRange -> {{startTime, startTime + window}, {0, ylim}}, 
   AxesOrigin -> {0, 0}, Frame -> True, FrameStyle -> Blue, 
   Background -> White, PlotStyle -> Blue, AxesStyle -> Blue, 
   ImageSize -> {550, 350}, ImagePadding -> 35]],
 {{startTime, 0.0, "Starting Week"}, 0, 1., Appearance -> "Labeled"},
 {{window, 0.1, "Number of Weeks"}, 0.1, 52., Appearance -> "Labeled"},
 {{ylim, 150000, "y limit"}, 1, 150000, Appearance -> "Labeled"},
 {yChosen, yTypes},
 TrackedSymbols -> True,
 AutorunSequencing -> {1, 2}
 ] 

enter image description here

share|improve this question
add comment

3 Answers

Well, you could do this, but when you flip types, the current value of lim can be out of range depending on current type until you click on the slider again to correct it. But this can be easily fixed in the code if you know the scaling needed.

For example if you in type2 and lim is say 100, and then click on type1 where the max is only one, then now lim will be out of range. But again, you can scale this in the code, inside the same If you see below, so that it will be automatic as well.

Manipulate[

 {limMin, limMax} = If[yChosen == "Type1", {0, 1}, {0, 15000}];

 Module[{week, y},
  yColumn = (Position[yTypes, yChosen][[1]])[[1]] + 1;
  y = Part[mySubset, All, yColumn];
  week = Part[mySubset, All, 1]/10080;

  ListPlot[Transpose[{week, y}], Joined -> True, 
   PlotRange -> {{startTime, startTime + window}, {0, ylim}}, 
   AxesOrigin -> {0, 0}, Frame -> True, FrameStyle -> Blue, 
   Background -> White, PlotStyle -> Blue, AxesStyle -> Blue, 
   ImageSize -> {550, 350}, ImagePadding -> 35]],

 {{startTime, 0.0, "Starting Week"}, 0, 1.,Appearance -> "Labeled"}, 
 {{window, 0.1, "Number of Weeks"}, 0.1, 52., Appearance -> "Labeled"},

 {{ylim, lim, "y limit"}, limMin, limMax, Appearance -> "Labeled"},

 {yChosen, yTypes},
 {{lim, 0.5}, None},
 {{limMin, 0}, None},
 {{limMax, 1}, None},

 TrackedSymbols -> True,
 AutorunSequencing -> {1, 2}
 ]
share|improve this answer
    
Thanks for your help! –  MLD Mar 15 '13 at 1:30
add comment

In the

tutorial/AdvancedManipulateFunctionality

there is a section called "Interdependent Controls" that has an example and some warnings about what to expect when you do this kind of thing.

share|improve this answer
add comment
 mySubset = {{0.`, 0.`, 0.`}, {60.`, 78069.`, 0.52046`}, 
 {120.`, 81417.`, 0.54278`}, {180.`, 84765.`, 0.5651`}, 
 {240.`, 88113.`, 0.58742`}, {300.`, 91461.`, 0.60974`}, 
 {360.`, 94809.`, 0.63206`}, {420.`, 98157.`, 0.65438`},
 {480.`, 101505.`, 0.6767`}, {540.`, 104853.`, 0.69902`}, 
 {600.`, 108201.`, 0.72134`}, {660.`, 111549.`, 0.74366`}, 
 {720.`, 114897.`, 0.76598`}, {780.`, 118245.`, 0.7883`}, 
 {840.`, 121593.`, 0.81062`}, {900.`, 124941.`, 0.83294`}, 
 {960.`, 128289.`, 0.85526`}, {1020.`, 131637.`, 0.87758`}, 
 {1080.`, 134985.`, 0.8999`}, {1140.`, 138333.`, 0.92222`}};

With slight modification of the control yChosen in OP's code, one can specify the limits of ylim without having to introduce new controls:

  Manipulate[Module[{week, y},
  y = Part[mySubset, All, yChsn + 1];
  week = Part[mySubset, All, 1]/10080;
  ListPlot[Transpose[{week, y}], Joined -> True,
  PlotRange -> {{startTime, startTime + window}, {0, ylim}},
  AxesOrigin -> {0, 0},
  Frame -> True, FrameStyle -> Blue, Background -> White, 
  PlotStyle -> Blue, AxesStyle -> Blue, ImageSize -> {550, 350}, ImagePadding -> 35]],
 {{startTime, 0.0, "Starting Week"}, 0, 1., Appearance -> "Labeled"},
 {{window, 0.1, "Number of Weeks"}, 0.1, 52., Appearance -> "Labeled"},
 {{ylim, 1., "y limit"}, 0, {1, 1500}[[yChsn]], {.1, 1}[[yChsn]], Appearance-> "Labeled"}, 
 {{yChsn, 1, "yChosen"}, {1 -> "Type1", 2 -> "Type2"}},
 TrackedSymbols -> True, AutorunSequencing -> {1, 2}]

As noted by @Nasser, the value of ylim will be out of range as one switches between Type1 and Type2. A better method is to associate two separate dynamic variables with ylimit and update ylim using the second argument of Dynamic inside the control yChosen. Using this approach, the slider ylim will "remember" its values associated with various values of yChosen.

  Manipulate[Module[{week, y},
  y = Part[mySubset, All, yChsn + 1];
  week = Part[mySubset, All, 1]/10080;
  ListPlot[Transpose[{week, y}], Joined -> True,
   PlotRange -> {{startTime, startTime + window}, {0, ylim}}, 
   AxesOrigin -> {0, 0},  Frame -> True, FrameStyle -> Blue, 
  Background -> White,   PlotStyle -> Blue,
  AxesStyle -> Blue, ImageSize -> {550, 350}, ImagePadding -> 35]],
 {{startTime, 0.0, "Starting Week"}, 0, 1., Appearance -> "Labeled"},
 {{window, 0.1, "Number of Weeks"}, 0.1, 52., Appearance -> "Labeled"},
 {{ylim, 1., "y limit"}, Automatic, 
   If[yChsn == 1, 
  Manipulator[Dynamic[j, (ylim = j; j = #) &], {0, 1, .1}, Appearance -> "Labeled"], 
  Manipulator[Dynamic[i, (ylim = i; i = #) &], {0, 1500, 1}, Appearance -> "Labeled"]] &}, 
  {{yChsn , 1, "yChosen"}, {1 -> "Type1", 2 -> "Type2"}, 
  SetterBar[  Dynamic[yChsn , (yChsn = #; 
   ylim = If[yChsn == 1, j, i]) &], {1 -> "Type1", 2 -> "Type2"}] &},
  {{i, 1.}, None}, {{j, 1.}, None},
  TrackedSymbols -> True, AutorunSequencing -> {1, 2}]
share|improve this answer
    
Thank-you, this is great, however I did not specify in the original question that I want the script to be used for data with any number of y types and I am currently unsure how to modify your answer to do so. –  MLD Mar 15 '13 at 1:29
    
@MLD, that's a good question. I don't have quick answer off the top of my head. I will update if I find an approach that works for the general case. –  kguler Mar 15 '13 at 1:53
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.