1
$\begingroup$

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

$\endgroup$

3 Answers 3

3
$\begingroup$

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}
 ]
$\endgroup$
0
3
$\begingroup$

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.

$\endgroup$
2
$\begingroup$
 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}]
$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – MLD
    Mar 15, 2013 at 1:29
  • $\begingroup$ @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. $\endgroup$
    – kglr
    Mar 15, 2013 at 1:53

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.