Mathematica动态绘制矩阵数据

时间:2011-12-13 10:26:44

标签: dynamic matrix wolfram-mathematica plot

我试图使用Mathematica 7动态绘制矩阵中包含的数据。数据包含在其中,通过化学模型获得。

[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         ]

事实是,矩阵尺寸是2001 * 1476(名称为2000步和第一行,年份为1475个化合物+ 1列),非常重。 我试图绘制任何具有浓度/年份图的化合物。这工作

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

其中数据是矩阵,化合物是根据模型化合物数量设置的变量(此处为1475)。 “compound”是滑块的标签。 问题是,滑块移动得快到几厘米浏览1400多个项目。 我试着用

做一个下拉菜单
MenuView[
  Table[
    ListLogLogPlot[data[[All, {1, i}]],PlotLabel -> data[[1, i]]], {i, 2, compounds}
  ]
]

它也有效,但这是一个处理器杀手程序(在执行16个内核的Xeon 16核服务器上超过10分钟),因为Mathematica尝试在显示所有图之前绘制所有图。此外,下拉列表没有名称,只有一系列数字(对于C8H14N +,颗粒为1,氢为1至1475),即使该图有名称。

我正在寻找一种仅按需绘制图形的方法,名称显示在下拉列表中(如果默认情况下需要H)。或者我可以输入化合物名称的字段。这似乎可以通过 Dynamic [] 命令实现,但我无法使其正常工作。

由于

3 个答案:

答案 0 :(得分:7)

迈克的建议很好,但如果您不想将其放入数据库,请使用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

要获取弹出菜单,请使用控制器规范的{i,listofvalues}语法。

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

enter image description here

这在我的系统上运行得相当快。 (两岁的MacBook Pro)

发烧友版本:

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

如果您只想逐步浏览图像,请单击滑块控制器旁边的小加号以获得更详细的控件。

enter image description here

答案 1 :(得分:5)

要在InputField中输入名称,您可以执行类似

的操作
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] &}]

此处,compounds是化合物所有名称的列表。 If中的Manipulate语句用于检查InputField中输入的名称是否为有效化合物。

其他人已经为您提供了创建一个大弹出列表的方法。如果您不想滚动1475个化合物的弹出列表,可以考虑将弹出列表拆分为子列表。例如,这会将整个化合物列表拆分为n=50元素的子列表,这可能使其更容易导航

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}
 ]
]

例如,

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

这看起来像

popup lists

答案 2 :(得分:3)

对于此大小的数据集,我建议(最佳)将其全部存储在数据库中,并使用DatabaseLink根据需要调用内容。然后将控制器(如弹出菜单)链接到SQLExecute代码或其他SQL函数。像这样的碎片会起到这样的作用:

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]
]

}]
]

实际上,您可能希望添加其他弹出窗口并进行连接等等。

修改

不使用数据库但按要求使用输入字段的替代方法:

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]]]
    ]

   }]
 ]

对于这个大小的规则列表,你可能想要使用我想象的Dispatch。看看时机如何。看起来这是您正在运行的某种实验,因此我的第一选择仍然是将其转储到数据库中。

进一步编辑

如果你依赖输入字段,那么你需要通过插入条件来解释笨拙的输入,这样Mma只会尝试绘制y是否为整数。

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