我试图使用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 [] 命令实现,但我无法使其正常工作。
由于
答案 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]
要获取弹出菜单,请使用控制器规范的{i,listofvalues}
语法。
Manipulate[
ListLogLogPlot[testdata[[All, {1, i}]],
PlotLabel -> testdata[[1, i]]], {i, Range[2, 1475]},
ContinuousAction -> False]
这在我的系统上运行得相当快。 (两岁的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]
如果您只想逐步浏览图像,请单击滑块控制器旁边的小加号以获得更详细的控件。
答案 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];
这看起来像
答案 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]
]