2011-12-15 8 views
3

Я пытаюсь сделать динамическое количество выпадающих меню в сюжете, чтобы построить множество кривых. У меня previously запросил помощь для построения этих данных, и это сработало хорошо.Mathematica: динамическое число меню

Первое

Needs["PlotLegends`"] 

Вот пример данных (не реальные цифры, так как они waaay слишком долго).

data={{year, H, He, Li, C, O, Si, S}, 
{0, .5, .1, .01, 0.01, 0.01, 0.001, 0.001}, 
{100, .45, .1, .01, 0.01, 0.01, 0.001, 0.001}, 
{200, .40, .1, .01, 0.01, 0.01, 0.001, 0.001}, 
{300, .35, .1, .01, 0.01, 0.01, 0.001, 0.001}} 

The соединений переменная число соединений + 1

compounds=8 

На данный момент мой код это один

Manipulate[ 
ListLogLogPlot[ 
    {data[[All, {1, i}]], 
    data[[All, {1, j}]], 
    data[[All, {1, k}]]}, 
    PlotLegend -> {data[[1, i]], 
       data[[1, j]], 
       data[[1, k]]} 
], 
{{i, 2, "Compound 1"},Thread[Range[2, compounds] -> Drop[data[[1]], 1]]}, 
{{j, 3, "Compound 2"},Thread[Range[2, compounds] -> Drop[data[[1]], 1]]}, 
{{k, 4, "Compound 2"},Thread[Range[2, compounds] -> Drop[data[[1]], 1]]}, 
ContinuousAction -> False 
] 

Mathematica graphics

Как вы можете видеть , Я могу легко добавить соединение с помощью duplicati каждая из трех строк (данные, легенда и дескриптор меню), но она хромает и неэффективна. Построение набора занимает около 20 секунд, поэтому здесь около 1 минуты (и я использую довольно эффективный кластер).

Есть ли решение добавить небольшое меню или поле, где я могу добавить количество соединений для построения, поэтому отобразится нужное количество меню? Мне не нужно больше 7 участков, но эффективность ...

Номера 2, 4, 16 являются значениями по умолчанию для построения. Я могу составить список со значениями по умолчанию (2, 14, 16, и некоторые другие я могу выбрать), или они могут быть установлены на 2.

Благодарности

+1

Ваш код не работает, он не является полным. Что такое «данные»? Лучше отправить небольшой полный пример, который фактически запускается. – Nasser

+0

Я добавил часть данных, которые я использую. –

ответ

5

Вы могли бы сделать что-то вроде этого

Manipulate[ 
ListLogLogPlot[data[[All, {1, #}]] & /@ i], 
{{n, 3, "# compounds"}, Range[7], 
    Dynamic[If[Length[i] != n, i = PadRight[{2, 4, 16}, n, 2]]; 
    PopupMenu[#, Range[7]]] &}, 
{{i, {2, 4, 16}}, ControlType -> None}, 
Dynamic[Column[ 
    Labeled[PopupMenu[Dynamic[i[[#]]], 
     Thread[Range[2, compounds] -> Drop[data[[1]], 1]]], 
     Row[{"Compound ", #}], Left] & /@ Range[n]] 
] 
] 

Mathematica graphics

Без PlotLegend это выполняется довольно быстро для набора случайных данных размером около 1000x1000 элементов. Если я включу опцию PlotLegend в ListLogLogPlot, это замедлит довольно много, так что это может быть причиной того, что ваш код был настолько медленным.

+0

Это работает отлично и быстро. Я не знаком с этим видом заговора, и неправильное размещение функции легенды замедляло все. Благодарю. –

+0

В этом коде есть ошибка (по крайней мере, когда вы пытаетесь заставить это работать с предоставленными данными). Числа 16 должны быть заменены числом, не большим, чем количество соединений. Диапазон [7] может быть заменен диапазоном [соединения-1] –

+0

Изменение на i = PadRight [i, n, 2] позволяет сохранить существующие варианты - те, которые все еще остаются, - при изменении значения n. –

4

Как о чем-то вроде:

Manipulate[ 
Manipulate[ ListLogLogPlot[Table[Subscript[x, n], {n, 1, numCompounds}]], 
    [email protected][Sequence,Table[{{Subscript[x, n], n + 1, "Compound " <> [email protected]}, 
    Thread[Range[2, compounds] -> Drop[data[[1]], 1]]}, {n, 1, 
    numCompounds}]], ContinuousAction -> False], 
{{numCompounds, 3}, 1, compounds - 1, 1}] 

Mathematica graphics

4

Я думал, что добавлю версию DM. Если вы похожи на меня, вы можете найти это проще, чем использовать манипуляции. Это, по сути, DM-версия ответа Хайке.

DynamicModule[{data,compounds,n=1,c={2},labels}, 

    data=yourData; 

    compounds=Length[data[[1]]]; 
    [email protected]@@Transpose[{Range[7],data[[1,2;;]]}]; 

    Column[{ 
    Dynamic[ 
     Grid[ 
     Join[ 
      {{"no. of compounds",PopupMenu[Dynamic[n],Range[7]]}}, 
      Table[ 
      With[{i=i}, 
       c=PadRight[c,n,2]; 
       {"compound"<>ToString[i], PopupMenu[Dynamic[c[[i]]],labels]} 
      ], 
      {i,n} 
      ] 
     ], 
     Alignment->{{Right,Left},Center} 
     ], 
     TrackedSymbols:>{n} 
    ], 
    [email protected][data[[All,{1,#}]]&/@c] 
    }] 
] 

Mathematica graphics

Я использовал сетку, потому что она позволяет легко держать все контроллеры и их метки выровненные. PadRight[c,n,2] позволяет сохранить текущие настройки, если вы измените значение n. Я бы избегал сюжетных легенд и всегда делал свой собственный.

Смежные вопросы