Mathematica: динамическое количество меню - PullRequest
3 голосов
/ 15 декабря 2011

Я пытаюсь составить динамическое количество выпадающих меню на графике, чтобы построить различное количество кривых. Я ранее запрашивал помощь в построении этих данных, и это работало хорошо.

Первым делом

Needs["PlotLegends`"]

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

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

Переменная составов - это число соединений + 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

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

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

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

Спасибо

Ответы [ 3 ]

5 голосов
/ 15 декабря 2011

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

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, он сильно замедлится, что может быть причиной того, что ваш код был таким медленным.

4 голосов
/ 16 декабря 2011

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

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

  data=yourData;

  compounds=Length[data[[1]]];
  labels=Rule@@@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}
    ], 
    Dynamic@ListLogLogPlot[data[[All,{1,#}]]&/@c]  
  }]
]

Mathematica graphics

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

4 голосов
/ 15 декабря 2011

Как насчет чего-то вроде:

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

Mathematica graphics

...