2011-12-13 70 views
5

我想用Mathematica 7動態繪製包含在矩陣中的數據。數據包含在它中,像這樣,通過化學模型獲得。Mathematica動態繪製矩陣數據

[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這裏)的數量。 「複合」是滑塊的標籤。 問題是,當幾釐米瀏覽1400多件商品時,滑塊移動得很快。 我試圖做一個下拉菜單,

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

它也可以,但這是一個處理器的殺手過程(執行16個內核至強16核服務器上10+分鐘),作爲數學嘗試繪製在顯示任何圖表之前的所有圖表。此外,該下拉菜單中沒有名稱,只是一系列數字(對於C8H14N +,Grain-,氫爲1到1475),即使該圖有一個名稱。

我正在尋找一種只按需求繪製圖表的方式,並在下拉列表中顯示名稱(如果需要,默認爲H)。或者我可以輸入化合物名稱的字段。這似乎可能與動態[]命令,但我沒有設法使其正常工作。

感謝

+0

'20001 x 1476'實際上是一個相當溫和的矩陣大小。你應該可以在內存中充分利用它,而不必依賴數據庫。 –

回答

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

+0

這工作真的很棒。謝謝。 –

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

    }] 
] 

對於這個尺寸,你可能會想使用派遣我想像的規則列表。看看時機如何。看起來這是你正在運行的某種實驗,所以我的第一選擇仍然是將其轉儲到數據庫中。

進一步編輯

如果你依靠輸入字段,那麼你將需要通過插入一個條件佔笨拙的打字,使MMA的只嘗試繪製如果y是一個整數。

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

使用數據庫可能會略微矯枉過正。他的矩陣只有大約300萬個元素,即使在我4歲的筆記本電腦上,Mathematica也能愉快地處理這些元素。不過,如果您擁有更大的數據集,這是一個好主意,尤其是如果它已經在數據庫中。 –

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是化合物的所有名稱的列表。 Manipulate中的If聲明用於檢查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