2011-12-25 14 views
6

Por favor considerar:Nested Manipular en Mathematica

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

Manipulate[ 
      Manipulate[ 
         Graphics[{ 
           Black, Rectangle[{0, 0}, {5, 5}], 
           White,[email protected][subID][[i]] 
           }, 
           ImageSize -> {400, 300}], 
      {i,Range[[email protected][subID]]}], 
{subID, {"subA", "subB"}}] 

enter image description here

Siempre que pointSO[subID] produce en realidad a listas de diferente longitud, hay una manera de evitar tener 2 Manipulate dado que una de la variable manipulada depende ¿en el otro?

+0

Como es, ambas listas son de la misma longitud. Quizás usando 'listlength [" subA "] = 5; listlength ["subB"] = 9; Función [subID, pointSO [subID] = RandomInteger [{1, 4}, {listlength [subID], 2}]] @ @ "subA", "subB"}; 'ilustra el problema que surge con Manipular solo – kglr

+0

Mi solución funciona bien con listas de diferente duración. El manipulador para i se ajusta dinámicamente. Creo que el principal problema puede deberse a que no se especifica un valor predeterminado para i. – Timo

+0

... Debe establecer explícitamente 'ControlType -> SetterBar'en la Manipulación interna para evitar diferentes controles en la Manipulación interna para' subA' y 'subB'. – kglr

Respuesta

5

Soy no seguro de que me dieron exactamente lo que está pidiendo, pero pensé que lo que quiere es algo como lo siguiente:

Dada una interfaz de usuario con una variable, digamos una matriz que puede cambiar en tamaño, y otra variable (dependiente), que representa, por ejemplo, un índice en la matriz actual que desea utilizar desde la interfaz de usuario para indexar en la matriz.

Pero no desea arreglar el diseño de la variable de índice en la IU, ya que depende, en tiempo de ejecución, del tamaño de la matriz, que puede cambiar con la segunda variable.

Aquí hay un manipular, que tiene una interfaz de usuario que tiene una variable de control de índice, que se actualiza dinámicamente en la interfaz de usuario a medida que cambia el tamaño de la matriz.

Utilicé SetterBar para el índice (la variable dependiente) pero también puede usar el control deslizante. SetterBar dejó más claro en la interfaz de usuario lo que está cambiando.

Cuando cambia la longitud de la matriz, la variable de control de índice actualiza automáticamente su índice máximo permitido que se utilizará para coincidir con la longitud actual de la matriz.

Al acortar la matriz, el índice también se reducirá.

No estoy seguro de si esto es lo que quiere, pero si, se puede ajustar este enfoque para encajar en su problema

Manipulate[ 

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

[email protected][{ 
    {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

actualización 8: 30 PM fyi, acaba de hacer una corrección al código anterior para agregar una lógica adicional necesaria.

+0

¡No sé si esto es lo que el OP quería o no, pero es útil para mí! : D – telefunkenvf14

+0

@Nasser, ¡Muchas gracias, muchos trucos muy útiles! – 500

2

Para evitar que el problema de i sea demasiado grande al cambiar de lista, puede agregar una declaración If[] al comienzo de Manipulate, p. Ej.

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, 
    [email protected][subID][[i]]}, ImageSize -> {400, 300}], 
{{subID, "subA"}, {"subA", "subB"}, SetterBar}, 
{{i, {}}, Range[[email protected][subID]], SetterBar}] 

Quizás es mejor reiniciar i al cambiar de una lista a otra.Esto se puede hacer haciendo algo como

Manipulate[ 
Graphics[{Black, Rectangle[{0, 0}, {5, 5}], White, 
    [email protected][subID][[i]]}, ImageSize -> {400, 300}], 
{{subID, "subA"}, 
    SetterBar[Dynamic[subID, (i = {}; subID = #) &], {"subA", "subB"}] &}, 
{{i, {}}, Range[[email protected][subID]], SetterBar} 
] 
+0

¡Muchas gracias! – 500

2

Una implementación alternativa que conserva la configuración de selección para cada conjunto de datos:

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, 
[email protected]@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" -> 
    [email protected][ 
    SetterBar[Dynamic[j, (k = j; j = #) &], 
    Range[[email protected]["subA"]], Appearance -> "Button", 
    Background -> Yellow]], 
"subB" -> 
    [email protected][ 
    SetterBar[Dynamic[i, (k = i; i = #) &], 
    Range[[email protected]["subB"]], Appearance -> "Button", 
    Background -> Cyan]]}, Dynamic[subID]]}]] 

ejemplos salida:

data set subB

data set subA

+0

@MrW gracias; acaba de arreglar el error. – kglr

+0

¡Votación felizmente invertida! –