如何在ListPlots中注释多个数据集

问题描述:

通常我必须同时可视化多个数据集,通常在ListPlot或其Log-companions中。由于数据集的数量通常大于容易区分的线条样式的数量,并且创建大量的情节图例仍然有些不妥协,所以我仍在寻找一种在我的地块中注释不同线条/集合的好方法。工具提示在屏幕上工作时很好,但如果我需要抠图,他们无法帮助。如何在ListPlots中注释多个数据集

最近,我与网格选项枚举我的数据集起到了一圈,发现了一些奇怪的东西

GraphicsGrid[Partition[Table[ListPlot[ 
[email protected] 
Table[{Sin[x], Cos[x], Tan[x], Cot[x]}, {x, 0.01, 10, 0.1}], 
PlotMarkers -> {"1", "2", "3", "4"}, Mesh -> i, Joined -> True, 
PlotLabel -> "Mesh\[Rule]" <> ToString[i], ImageSize -> 180], {i, 
1, 30}], 4]] 

结果看起来像这样我的机器上(Windows 7的64位,数学8.0.1):

 Mesh = i, with i running from 1 to 30

有趣的是,对于网格 - > 2,8和10,结果看起来像我预期的那样,其余的则不然。我不明白Mesh选项,或者它不理解我。

这里是我的问题:

  1. 是网格ListPLot窃听或我错误地使用它?
  2. 我该如何移动连续集合的网格点以避免叠印?
  3. 你有任何其他建议如何注释/枚举一个情节中的多个数据集?
+3

Mesh'和''之间的相互作用的PlotMarkers'在上来的问题[本SO问题](http://stackoverflow.com/questions/4789047/custom-intervals-of-markers-在-数学-plotmarkers/4790805#4790805)。我当时向世界资源研究所报告,技术支持将其转交给开发小组审视。希望它会在下一个版本中得到修复。 – Simon

+1

我很好奇为什么有些网格选项可以工作,而其他许多选项则不能。 –

+2

至于你的第三个问题,你可能想看看我在这里使用的图:http://stackoverflow.com/questions/5745298/how-do-i-access-the-stackoverflow-api-from-mathematica/5745783 #5745783。这涉及手动注释(可以使其半自动工作)。我觉得最终结果在视觉上比许多其他方法更令人满意。 –

你可以尝试沿着这些线。使每一行成为一个按钮,点击后即可识别自己。

plot=Plot[{Sin[x],Cos[x]},{x,0,2*Pi}]; 
sinline=plot[[1,1,3,2]]; 
cosline=plot[[1,1,4,2]]; 
message=""; 
altplot=Append[plot,PlotLabel->Dynamic[message]]; 
altplot[[1,1,3,2]]=Button[sinline,message="Clicked on the Sin line"]; 
altplot[[1,1,4,2]]=Button[cosline,message="Clicked on the Cos line"]; 
altplot 

如果添加事件处理程序,你可以得到你点击的位置,并与相关定位标签的情节添加插图。以动态方式包裹情节,以便在每次点击按钮后自行更新。它工作正常。

在回应评论,这里是一个更全面的版本:

plot = Plot[{Sin[x], Cos[x]}, {x, 0, 2*Pi}]; 
sinline = plot[[1, 1, 3, 2]]; 
cosline = plot[[1, 1, 4, 2]]; 
AddLabel[label_] := (AppendTo[plot[[1]], 
    Inset[Framed[label, Background -> White], pt]]; 
    (* Remove buttons for final plot *) 
    plainplot = plot; 
    plainplot[[1, 1, 3, 2]] = plainplot[[1, 1, 3, 2, 1]]; 
    plainplot[[1, 1, 4, 2]] = plainplot[[1, 1, 4, 2, 1]]); 
plot[[1, 1, 3, 2]] = Button[sinline, AddLabel["Sin"]]; 
plot[[1, 1, 4, 2]] = Button[cosline, AddLabel["Cos"]]; 
Dynamic[EventHandler[plot, 
    "MouseDown" :> (pt = MousePosition["Graphics"])]] 

添加就行了标签点击。最终的注释图表设置为'plainplot',可打印和可复制,并且不包含动态元素。

[当天晚些时候]另一个版本,这次是通用的,并基于初始图表。 (使用Mark McClure解决方案的一部分。)对于不同的图,可以根据需要编辑'ff'和'spec'。

ff = {Sin, Cos, Tan, Cot}; 
spec = Range[0.1, 10, 0.1]; 
(* Plot functions separately to obtain line counts *) 
plots = Array[ListLinePlot[ff[[#]] /@ spec] &, [email protected]]; 
plots = DeleteCases[plots, Line[_?(Length[#] < 3 &)], Infinity]; 
numlines = Array[[email protected][plots[[#]], Line[_], Infinity] &, 
    [email protected]]; 
(* Plot functions together for annotation plot *) 
plot = ListLinePlot[#@spec & /@ ff]; 
plot = DeleteCases[plot, Line[_?(Length[#] < 3 &)], Infinity]; 
lbl = [email protected][ConstantArray[[email protected][[#]], 
     numlines[[#]]] &, [email protected]]; 
(* Line positions to substitute with buttons *) 
linepos = Position[plot, Line, Infinity]; 
Clear[line]; 
(* Copy all the lines to line[n] *) 
Array[(line[#] = plot[[Sequence @@ [email protected][[#]]]]) &, 
    [email protected]]; 
(* Button function *) 
AddLabel[label_] := (AppendTo[plot[[1]], 
    Inset[Framed[label, Background -> White], pt]]; 
    (* Remove buttons for final plain plot *) 
    plainplot = plot; 
    bpos = Position[plainplot, Button, Infinity]; 
    Array[(plainplot[[Sequence @@ [email protected][[#]]]] = 
     plainplot[[Sequence @@ Append[[email protected][[#]], 1]]]) &, 
    [email protected]]); 
(* Substitute all the lines with line buttons *) 
Array[(plot[[Sequence @@ [email protected][[#]]]] = Button[line[#], 
     AddLabel[lbl[[#]]]]) &, [email protected]]; 
Dynamic[EventHandler[plot, 
    "MouseDown" :> (pt = MousePosition["Graphics"])]] 

下面是它的外观。注释之后,可以将纯图形对象设置为'plainplot'变量。

Annotated Chart

+2

非常有趣的介绍!对于工具提示来说,这是一个不错的选择(特别是如果该行将以某种方式突出显示,例如将会变成粗体 - 我们不需要点击它,只需将鼠标放在它上面!)。谢谢。 +1 –

+0

非常好的想法,但是,它类似于Tooltip,如果你需要打印的情节,这往往是无用的。虽然介绍,这是一个很好的方法。 –

+3

@ Markus - 我已经添加了一个更完整的示例,它在放置标签后显示标签,因此可以打印带注释的图。 –

一种方法是单独生成图,然后将它们一起显示。由于PlotMarkers似乎在处理一个数据集时会发挥我们预期的效果,所以这会产生更像您的其他帖子的代码。我们可以使用ColorDataPlotStyle获得相同的颜色。这里的结果:

ff = {Sin, Cos, Tan, Cot}; 
plots = Table[ListLinePlot[ff[[i]] /@ Range[0.1, 10, 0.1], 
    PlotStyle -> {ColorData[1, i]}, 
    PlotMarkers -> i, Mesh -> 22], {i, 1, Length[ff]}]; 
(* Delete the spurious asymptote looking thingies. *) 
plots = DeleteCases[plots, Line[ll_?(Length[#] < 4 &)], Infinity]; 
Show[plots, PlotRange -> {-4, 4}] 

enter image description here

+0

+1,这是我使用的方法,因为有时您需要使用符号和颜色来跟踪几个额外的维度,并且没有什么效果。 – rcollyer

+0

我知道将上面的例子分解成单独的个体情节是一个解决方法 - 也许这是一条路。 –

你要密谋可计算的曲线或实际数据?

如果它是可计算的曲线,那么通常使用plot legend (key)。 您可以使用不同的宽度和粗细来区分灰度打印机上的线条。 PlotLegends文档中有很多示例。

如果它是真实数据,那么通常数据很稀疏,您可以使用PlotMarkers作为实际数据点(即,不指定Mesh)。您可以使用自动PlotMarkers,或者您可以使用自定义PlotMarkers包括BoxWhisker标记来指示各种不确定性。

+1

这确实是做这件事的标准方式。但是,PlotLegend软件包存在严重缺陷(请参阅http://stackoverflow.com/questions/3463437/plotting-legends-in-mathematica/3533152#3533152),另外,我觉得它有美学问题。 –

+0

@Sjoerd:我没有注意到这个问题。 'PlotLegend'重新调整'Plot'的方式并不好... – Simon