Mathematica:动态菜单数量

3
我正在尝试在图表中制作动态数量的下拉菜单,以绘制各种曲线。我之前曾请求帮助来绘制这些数据,并且效果很好。
首先,您需要使用JavaScript创建下拉菜单元素并将其添加到图表中。然后,您可以使用Plotly.js等库来绘制曲线并根据所选的下拉菜单值更新它们。您可以参考此处的示例代码。
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}}

compounds变量是化合物数量+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。

谢谢


1
你的代码无法运行,它还不完整。什么是“数据”?最好发布一个小的完整示例,确保可以正常运行。 - Nasser
我添加了一部分我使用的数据。 - A postdoc
3个回答

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图形

如果不使用PlotLegend,对于大约1000x1000元素的随机数据集,此代码运行得非常快。如果我在ListLogLogPlot中包含PlotLegend选项,则会明显减慢速度,这可能是您的代码速度缓慢的原因。


这个完美地运行,并且速度很快。我对那种绘图方式不熟悉,错误的图例函数放置拖慢了一切。谢谢。 - A postdoc
这段代码有一个问题(至少在尝试使用提供的数据时)。数字16应该替换为不大于化合物数量的数字。Range[7]可以替换为Range [compounds-1]。 - Sjoerd C. de Vries
我正在使用这段代码,因为它非常好用。但是,有没有办法识别曲线,比如给按钮着色、在按钮前面的文本上着色或绘制图例? - A postdoc
没关系,我已经找到了解决方案,只需添加 PlotLegend -> [data [[1,i]]]。 - A postdoc
1
@Billouman:如果你想要将按钮前面的文本着色为图中对应的颜色,你可以将 Row[{"Compound ", #}] 替换为类似于 Style[Row[{"Compound ", #}], ColorData[1][#]] 的内容(假设你正在使用 ListLogLogPlot 中的标准颜色)。 - Heike
显示剩余2条评论

4
像这样怎么样:
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


4

我想我可以提供一个 DM 版本。如果你和我一样,可能会发现使用 manipulate 不如这种方式更方便。这本质上是 Heike 回答的 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图形

我使用Grid,因为它允许您轻松地使所有控制器及其标签保持对齐。 PadRight[c,n,2] 可以使您在更改n的值时保留当前设置。我建议避免使用图例,而是自己制作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接