2011-12-13 7 views
5

Estoy tratando de trazar dinámicamente los datos contenidos en una matriz con Mathematica 7. Los datos están contenidos en ella de esta manera, obtenidos a través de un modelo químico.Dinámica de Mathematica para trazar los datos de la matriz

[year H He  Li  C  ... C8H14+,Grain- ] 
[0  0 0.03 0.009 1E-3 ... 0    ] 
[100 .1 0.03 0.009 1E-3 ... 0    ] 
[200 .2 0.03 0.009 1E-3 ... 0    ] 
[300 .2 0.03 0.009 1E-3 ... 0    ] 
[... ... ... ...  ... ... ...   ] 
[1E6 .5 0.03 0.003 1E-8 ... 1E-25   ] 

La verdad es que las dimensiones de la matriz son de 2001 * 1476 (2000 pasos y primera línea para el nombre, y 1475 compuestos + 1 de columna para año), muy pesadas. Estoy intentando trazar cualquier compuesto con una gráfica de concentración/año. Esto funciona

Manipulate[ 
    ListLogLogPlot[data[[All, {1, i}]], PlotLabel -> data[[1, i]] ], 
    {{i, 2, "Compound"}, 2, compounds, 1} 
] 

donde datos es la matriz, y compuestos un conjunto variable al número de compuestos modelizado (1475 aquí). "compuesto" es una etiqueta para el control deslizante. El problema es que el control deslizante se mueve mucho más rápido ya que algunos centímetros exploran más de 1400 elementos. he tratado de hacer un menú desplegable con

MenuView[ 
    Table[ 
    ListLogLogPlot[data[[All, {1, i}]],PlotLabel -> data[[1, i]]], {i, 2, compounds} 
    ] 
] 

También funciona, pero esto es un proceso asesino procesador (10 + minutos en un servidor Xeon de 16 núcleos ejecución de 16 granos), como Mathematica tratar de graficar todas las parcelas antes de mostrar cualquiera de ellas. Además, el menú desplegable no tiene nombre, solo una serie de números (1 para hidrógeno a 1475 para C8H14N +, Grano-), aunque la trama tenga un nombre.

Lo que estoy buscando una forma de trazar un gráfico solo a pedido, con un nombre que se muestra en la lista desplegable (y si es necesario H de forma predeterminada). O un campo donde puedo ingresar el nombre del compuesto. Esto parece posible con el comando Dynamic [], pero no logro hacerlo funcionar correctamente.

Gracias

+0

'20001 x 1476' es en realidad un tamaño de matriz bastante doméstico. Debería poder jugar con esto en la memoria sin tener que depender de una base de datos. –

Respuesta

7

sugerencia de Mike es buena, pero si usted no quiere ir al esfuerzo de ponerlo en una base de datos, utilice la opción ContinuousAction->False.

testdata = 
    Join[{Table[ToString[series[i-1]], {i, 1475}]}, 
    RandomReal[{1., 100.}, {2000, 1476}]]; 

Manipulate[ 
ListLogLogPlot[testdata[[All, {1, i}]], 
    PlotLabel -> testdata[[1, i]]], {{i, 2, "Compound"}, 2, 1475, 1}, 
ContinuousAction -> False] 

enter image description here

para conseguir un menú emergente, utilice la sintaxis {i,listofvalues} para la especificación del controlador.

Manipulate[ 
ListLogLogPlot[testdata[[All, {1, i}]], 
    PlotLabel -> testdata[[1, i]]], {i, Range[2, 1475]}, 
ContinuousAction -> False] 

enter image description here

Esto funciona bastante rápido en mi sistema. (Dos años de edad MacBook Pro)

Una versión más elegante:

spec = Thread[Range[2, 1476] -> Table[ToString[series[i]], {i, 1475}]]; 

Manipulate[ 
ListLogLogPlot[testdata[[All, {1, i}]], 
    PlotLabel -> testdata[[1, i]]], {{i, 2, "Compound"}, spec}, 
ContinuousAction -> False] 

enter image description here

Y si todo lo que quiere hacer es paso a través de las imágenes, haga clic en el poco más al lado de un controlador deslizante para obtener controles más detallados.

enter image description here

+0

Esto funciona realmente genial. Gracias. –

3

Para los conjuntos de datos de este tamaño se lo recomiendo (como óptimo) almacenar todo en una base de datos y el uso de DatabaseLink a llamar las cosas como se requiere. Luego, vincule sus controladores, como menús emergentes, al código SQLExecute u otras funciones SQL. Los fragmentos de este tipo serían el tipo de cosa que haría el trabajo:

DynamicModule[{x,data, ...}, 

Column[{ 

PopupMenu[Dynamic[x], {1 -> "category 1", 2 -> "category 2", 3 -> "category 3", ...}], 

Dynamic[ 

data = SQLExecute[conn, "SELECT * FROM myDatabase.table WHERE my_id = `1`;", {x}]; 
ListLogLogPlot[data] 
] 

}] 
] 

En realidad, puede que desee ser la adición de ventanas emergentes adicionales y hacer combinaciones y así sucesivamente.

EDITAR

alternativa que no utiliza bases de datos pero utiliza los campos de entrada conforme a lo solicitado:

DynamicModule[{x = "He", rules, y}, 

rules = Rule @@@ Transpose[{data[[1, All]], Range[Length[data[[1, All]]]]}]; 

Column[{ 
    InputField[Dynamic[x], String], 

    Dynamic[ 
    y = x /. rules; 
    ListLogLogPlot[data[[All, {1, y}]], PlotLabel -> data[[1, y]]] 
    ] 

    }] 
] 

Para listas reglas de este tamaño que probablemente desee utilizar Despacho me imagino. Vea cómo va el tiempo para eso. Parece que este es un tipo de experimento que está ejecutando, por lo que mi primera opción sigue siendo verterlo en un DB.

hacer otras modificaciones

Si usted está confiando en los campos de entrada, entonces tendrá que dar cuenta de la tipificación torpe mediante la inserción de un condicional de manera que sólo se Mma intenta trazar si y es un entero.

If[IntegerQ[y], 
ListLogLogPlot, 
Spacer[0] 
] 
+1

Usar una base de datos puede ser un poco exagerado para esto. Su matriz es solo alrededor de ~ 3 millones de elementos que Mathematica maneja feliz incluso en mi computadora portátil de 4 años. Aún así, esta es una buena idea si tiene un conjunto de datos aún mayor, especialmente si ya está en una base de datos. –

5

Para introducir nombres en una InputField, usted podría hacer algo como

compounds = Rest[data[[1]]]; 
Manipulate[ 
If[MemberQ[compounds, compound], i = Position[compounds, compound][[1, 1]] + 1]; 
ListLogLogPlot[data[[All, {1, i}]], PlotLabel -> data[[1, i]]], 
{{i, 2}, None}, 
{{compound, data[[1, 2]], "Compound"}, InputField[#, String] &}] 

Aquí, compounds es una lista de todos los nombres de los compuestos. La instrucción If en Manipulate es comprobar si el nombre introducido en el InputField es un compuesto válido o no.

Otros ya le han dado formas de crear una gran lista emergente. Si no desea desplazarse por una lista emergente de 1475 compuestos, podría considerar dividir la lista emergente en sublistas. Por ejemplo, esto podría dividir toda la lista de compuestos en sublistas de n=50 elementos que podrían hacer que sea más fácil de navegar

compounds = Rest[data[[1]]]; 
With[{n = 50}, 
Manipulate[ 
    i = 1 + Position[compounds, name][[1, 1]]; 
    ListLogLogPlot[data[[All, {1, i}]], PlotLabel -> data[[1, i]]], 
    {{i, 2}, None}, 
    {{indexlist, 1, "Indices"}, 
    Table[i -> ToString[(i - 1) n + 1] <> " through " <> 
    ToString[Min[i n, Length[compounds]]], 
    {i, Ceiling[Length[compounds]/n]}], PopupMenu}, 
    {{name, compounds[[1]], "Compound"}, 
    compounds[[n (indexlist - 1) + 1 ;; 
     Min[Length[compounds], n indexlist]]], PopupMenu} 
] 
] 

Por ejemplo, para

data = Table[Join[{i}, RandomReal[{0, 1}, 1000]], {i, 1000}]; 
data = Join[{Prepend[Table["list " <> ToString[i], {i, 1000}], "year"]}, data]; 

esto parece

popup lists

Cuestiones relacionadas