Mathematica中的嵌套操作

时间:2011-12-25 16:29:28

标签: wolfram-mathematica

请考虑:

Function[subID, 
         pointSO[subID] = RandomInteger[{1, 4}, {5, 2}]] /@ {"subA", "subB"};

Manipulate[
           Manipulate[
                      Graphics[{
                                Black, Rectangle[{0, 0}, {5, 5}],
                                White,Point@pointSO[subID][[i]]
                               },
                               ImageSize -> {400, 300}], 
           {i,Range[Length@pointSO[subID]]}], 
{subID, {"subA", "subB"}}]

enter image description here

如果pointSO[subID]实际上产生了不同长度的列表,是否有办法避免2 Manipulate给定一个被操纵变量取决于另一个?

3 个答案:

答案 0 :(得分:5)

确定我得到了你所要求的,但我想你想要的是如下:

给定具有一个变量的UI,例如可以改变大小的数组,以及另一个(从属)变量,它表示要从UI使用的索引到当前数组中以索引到数组中。 / p>

但是你不想修改UI中的索引变量布局,因为它在运行时依赖于数组的大小,而数组的大小可以使用第二个变量进行更改。

这是一个操作,它有一个具有索引控制变量的UI,当数组大小发生变化时,它会在UI上动态更新。

我使用SetterBar作为索引(因变量),但您也可以使用滑块。 SetterBar在UI上更清楚地了解了哪些内容正在发生变化。

当您更改数组的长度时,索引控制变量会自动更新其最大允许索引,以用于匹配数组的当前长度。

缩小数组时,索引也会缩小。

我不确定这是否是您想要的,但如果是,您可以调整此方法以适应您的问题

Manipulate[

 Grid[{
   {Style[Row[{"data[[", i, "]]=", data[[i]]}], 12]},
   {MatrixForm[data], SpanFromLeft}
   },
  Alignment -> Left, Spacings -> {0, 1}
  ],

 Dynamic@Grid[{
    {Text["select index into the array = "],
     SetterBar[Dynamic[i, {i = #} &], Range[1, Length[data]], 
      ImageSize -> Tiny,
      ContinuousAction -> False]
     },

    {
     Text["select how long an array to build = "],
     Manipulator[
      Dynamic[n, {n = #; If[i > n, i = n]; 
         data = Table[RandomReal[], {n}]} &],
      {1, 10, 1}, ImageSize -> Tiny, ContinuousAction -> False]
     , Text[Length[data]], SpanFromLeft
     }
    }, Alignment -> Left
   ],

 {{n, 2}, None},
 {{i, 2}, None},
 {{data, Table[RandomReal[], {2}]}, None},
 TrackedSymbols -> {n, i}
 ]

enter image description here

enter image description here

更新晚上8:30 fyi,只是修复了上面的代码,添加了一个必要的额外逻辑。

答案 1 :(得分:2)

为了避免在切换列表时i过大的问题,您可以在If[]的开头添加Manipulate语句,例如

Clear[pointSO];
MapThread[(pointSO[#] = RandomInteger[{1, 4}, {#2, 2}]) &, 
  {{"subA", "subB"}, {5, 7}}];

Manipulate[
 If[i > Length[pointSO[subID]], i = Length[pointSO[subID]]];
 Graphics[{Black, Rectangle[{0, 0}, {5, 5}], White, 
   Point@pointSO[subID][[i]]}, ImageSize -> {400, 300}],
 {{subID, "subA"}, {"subA", "subB"}, SetterBar},
 {{i, {}}, Range[Length@pointSO[subID]], SetterBar}]

在列表之间切换时,更好的是重置i。这可以通过执行类似

的操作来完成
Manipulate[
 Graphics[{Black, Rectangle[{0, 0}, {5, 5}], White, 
   Point@pointSO[subID][[i]]}, ImageSize -> {400, 300}],
 {{subID, "subA"}, 
   SetterBar[Dynamic[subID, (i = {}; subID = #) &], {"subA", "subB"}] &},
 {{i, {}}, Range[Length@pointSO[subID]], SetterBar}
]

答案 2 :(得分:2)

保留每个数据集的选择设置的替代实现:

listlength["subA"] = 5; listlength["subB"] = 9; 
Function[subID, 
pointSO[subID] = 
RandomInteger[{1, 4}, {listlength[subID], 2}]] /@ {"subA", "subB"};

Manipulate[
 Graphics[{Black, Rectangle[{0, 0}, {5, 5}], 
 Dynamic[If[subID == "subA", Yellow, Cyan]], PointSize -> .05, 
 Dynamic@Point@pointSO[subID][[k]]}, ImageSize -> {400, 300}], 
Row[{Panel[
SetterBar[
Dynamic[subID, 
(subID = #; k = If[subID == "subA", j, i]) &],{"subA", "subB"}, 
 Appearance -> "Button", Background -> GrayLevel[.8]]], "      ", 
PaneSelector[{"subA" -> 
  Dynamic@Panel[
    SetterBar[Dynamic[j, (k = j; j = #) &], 
     Range[Length@pointSO["subA"]], Appearance -> "Button", 
     Background -> Yellow]], 
 "subB" -> 
  Dynamic@Panel[
    SetterBar[Dynamic[i, (k = i; i = #) &], 
     Range[Length@pointSO["subB"]], Appearance -> "Button", 
     Background -> Cyan]]}, Dynamic[subID]]}]]

输出示例:

data set subB

data set subA