Вложенный манипулятор в Mathematica - PullRequest
6 голосов
/ 25 декабря 2011

Пожалуйста, примите во внимание:

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 ]

5 голосов
/ 26 декабря 2011

Я не уверен, что я получил именно то, что вы просите, но я подумал, что вы хотите что-то вроде следующего:

Учитывая UI с одной переменной, скажем, массив, который может измениться в размере, и другую (зависимую) переменную, которая представляет, скажем, индекс в текущий массив, который вы хотите использовать из UI для индексации в массив. 1005 *

Но вы не хотите исправлять макет переменной индекса в пользовательском интерфейсе, поскольку во время выполнения он зависит от размера массива, который можно изменить с помощью второй переменной.

Вот одна из манипуляций, которая имеет пользовательский интерфейс с переменной управления индексом, который динамически обновляется в пользовательском интерфейсе при изменении размера массива.

Я использовал SetterBar для индекса (зависимой переменной), но вы также можете использовать ползунок. SetterBar прояснил в пользовательском интерфейсе, что меняется.

Когда вы изменяете длину массива, переменная управления индексом автоматически обновляет свой максимально допустимый индекс, который будет использоваться для соответствия текущей длине массива.

Когда вы уменьшаете массив, индекс также сокращается.

Я не уверен, что это то, что вы хотите, но если это так, вы можете настроить этот подход в соответствии с вашей проблемой

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 вечера К вашему сведению, только что исправил приведенный выше код, добавив необходимую дополнительную логику.

2 голосов
/ 26 декабря 2011

Альтернативная реализация, которая сохраняет настройки выбора для каждого набора данных:

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

2 голосов
/ 26 декабря 2011

Чтобы избежать проблемы слишком большого размера 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}
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...