Wolfram mathematica 自适应网格线

Wolfram mathematica 自适应网格线,wolfram-mathematica,Wolfram Mathematica,我想使用网格线在2d图形上创建的效果,以显示多变量函数如何依赖于一个变量。不同变量的尺度差异很大,因此我的天真方法(我以前使用过)似乎不起作用 我目前拥有的示例: << ErrorBarPlots` Cmb[x_, y_, ex_, ey_] := {{N[x], N[y]}, ErrorBar[ex, ey]}; SetAttributes[Cmb, Listable]; ELP[x_, y_, ex_, ey_, name_] := ErrorListPlot[ Cmb[

我想使用网格线在2d图形上创建的效果,以显示多变量函数如何依赖于一个变量。不同变量的尺度差异很大,因此我的天真方法(我以前使用过)似乎不起作用

我目前拥有的示例:

<< ErrorBarPlots`
Cmb[x_, y_, ex_, ey_] := {{N[x], N[y]}, ErrorBar[ex, ey]};
SetAttributes[Cmb, Listable];

ELP[x_, y_, ex_, ey_, name_] :=
 ErrorListPlot[
  Cmb[x, y, ex, ey],
  PlotRange -> FromTo[x, y],
  PlotLabel -> name,
  Joined -> True, Frame -> True, GridLines -> GetGrid,
  ImageSize -> {600}
 ]
将导致:

还有我天真的GetGrid,它在某种意义上起作用:

FromTo[x_, y_] := Module[{dx, dy},
   dx = (Max[x] - Min[x])*0.1;
   dy = (Max[y] - Min[y])*0.1;
   {{Min[x] - dx, Max[x] + dx}, {Min[y] - dy, Max[y] + dy}}];
GetGrid[min_, max_] := Module[{step, i},
  step = (max - min)/100;
  Table[
   {min + i*step,
    If[Equal[Mod[i, 10], 0],
     Directive[Gray, Thick, Opacity[0.5]],
     If[Equal[Mod[i, 5], 0],
      Directive[Gray, Opacity[0.5]],
      Directive[LightGray, Opacity[0.5]]
      ]]},
   {i, 1, 100}]
  ]
问题: 如何使网格线与记号对齐

编辑:与

GetTicks[x_, y_] := Module[{dx, dy},
   dx = (Max[x] - Min[x])*0.1;
   dy = (Max[y] - Min[y])*0.1;
   {
    Min[x] - dx + Table[i*dx*1.2, {i, 1, 9}],
    Min[y] - dy + Table[i*dy*1.2, {i, 1, 9}]
    }];

ELP[x_, y_, ex_, ey_, name_] :=
 ErrorListPlot[
  Cmb[x, y, ex, ey],
  PlotRange -> FromTo[x, y],
  PlotLabel -> name,
  Joined -> True, Frame -> True, GridLines -> GetGrid, 
  FrameTicks -> GetTicks[x, y],
  ImageSize -> {600},
  AspectRatio -> 1
  ]
我可以得到:

这就好多了。但我想改变网格,而不是滴答声

编辑:@Sjoerd C.de Vries

您的解决方案实现了我想要归档的功能,并且可以正常工作。我还注意到,如果我取样本数据的前5个元素,那么绘图将是(元素被排序,回归线被添加)。


请注意,最左边的元素类似于脱离网格。

如果对
帧标记
网格线
使用相同的函数,它们将对齐


看,还有。我想您需要使用
ImageMargins
作为边框。

不要使用帧标记,而是正确移动网格。这是第一种方法。晚餐等着

getGrid[min_, max_] :=
 Module[{step, i},
  Print[{min, max}];
  step = 1/100;
  Table[
   {
    Floor[min, 0.1] + i*step,
    If[Equal[Mod[i, 10], 0], Directive[Gray, Thick, Opacity[0.5]],
     If[Equal[Mod[i, 5], 0], Directive[Gray, Opacity[0.5]],
      Directive[LightGray, Opacity[0.5]]
      ]
     ]
    },
   {i, 1, (Ceiling[max, 0.1] - Floor[min, 0.1])/step // Round}
   ]
  ]
使用适合网格的AspectRatio(可能是x和y范围的比率)


晚餐后更新

为了使它对不同的值范围(根据您的注释)更为健壮,我生成了将由
ListPlot
选择的刻度,并以此为基础执行步骤:

getGrid[min_, max_] :=
 Module[{step, i,j},
  i = Cases[(Ticks /. 
       AbsoluteOptions[ListPlot[{{min, min}, {max, max}}], 
        Ticks])[[1]], {a_, ___, {_, AbsoluteThickness[0.25`]}} :> a];
  step = i[[2]] - i[[1]];
  Table[
   {
    i[[1]] + j*step/10,
    If[Equal[Mod[j, 10], 0], Directive[Gray, Thick, Opacity[0.5]],
     If[Equal[Mod[j, 5], 0], Directive[Gray, Opacity[0.5]],
      Directive[LightGray, Opacity[0.5]]
      ]
     ]
    },
   {j, 0, 10 Length[i]}
   ]
  ]
得到纵横比,得到一个正方形光栅

getAspect[{{minX_, maxX_}, {minY_, maxY_}}] :=
 Module[{stepx, stepy, i, rx, ry},
   i = (Ticks /.AbsoluteOptions[ListPlot[{{minX, minY}, {maxX, maxY}}], Ticks]);
   rx = Cases[i[[1]], {a_, ___, {_, AbsoluteThickness[0.25`]}} :> a];
   stepx = rx[[2]] - rx[[1]];
   ry = Cases[i[[2]], {a_, ___, {_, AbsoluteThickness[0.25`]}} :> a];
   stepy = ry[[2]] - ry[[1]];
  ((maxY - minY)/stepy)/((maxX - minX)/stepx)
  ]

测试

ELP[x_, y_, ex_, ey_, name_] := 
 ErrorListPlot[Cmb[x, y, ex, ey], PlotLabel -> name, Joined -> True, 
  Frame -> True, GridLines -> getGrid, ImageSize -> {600}, 
  PlotRangePadding -> 0, AspectRatio -> getAspect[FromTo[x, y]], 
  PlotRange -> FromTo[x, y]]


ELP[{4124961/25000000, 27573001/100000000, 9162729/25000000, 
  44635761/100000000, 15737089/25000000, 829921/1562500, 
  4405801/4000000, 23068809/25000000, 329386201/100000000, 
  58079641/100000000}, {1/10, 1/5, 3/10, 2/5, 3/5, 1/2, 1/2, 1/2, 1/2,
   1/2}, {2031/(250000 Sqrt[10]), 5251/(500000 Sqrt[10]), 
  3027/(250000 Sqrt[10]), 1/100000 6681/(500000 Sqrt[10]), 
  3967/(250000 Sqrt[10]), 911/(62500 Sqrt[10]), 
  2099/(100000 Sqrt[10]), 4803/(250000 Sqrt[10]), 
  18149/(500000 Sqrt[10]), 7621/(500000 Sqrt[10])}, {1/2000, 1/1000, 
  3/2000, 1/500, 3/1000, 1/400, 1/400, 1/400, 1/400, 1/400}, "T2, m"]

在这里,我将y值除以20,将x值乘以10000,以显示网格仍然良好:


最终更新(我希望)

ELP[x_, y_, ex_, ey_, name_] := 
 ErrorListPlot[Cmb[x, y, ex, ey], PlotLabel -> name, Joined -> True, 
  Frame -> True, GridLines -> getGrid, ImageSize -> {600}, 
  PlotRangePadding -> 0, AspectRatio -> getAspect[FromTo[x, y]], 
  PlotRange -> FromTo[x, y]]


ELP[{4124961/25000000, 27573001/100000000, 9162729/25000000, 
  44635761/100000000, 15737089/25000000, 829921/1562500, 
  4405801/4000000, 23068809/25000000, 329386201/100000000, 
  58079641/100000000}, {1/10, 1/5, 3/10, 2/5, 3/5, 1/2, 1/2, 1/2, 1/2,
   1/2}, {2031/(250000 Sqrt[10]), 5251/(500000 Sqrt[10]), 
  3027/(250000 Sqrt[10]), 1/100000 6681/(500000 Sqrt[10]), 
  3967/(250000 Sqrt[10]), 911/(62500 Sqrt[10]), 
  2099/(100000 Sqrt[10]), 4803/(250000 Sqrt[10]), 
  18149/(500000 Sqrt[10]), 7621/(500000 Sqrt[10])}, {1/2000, 1/1000, 
  3/2000, 1/500, 3/1000, 1/400, 1/400, 1/400, 1/400, 1/400}, "T2, m"]
这使用FindDivisions作为。但是,根据Margus的要求,我使用了毫米纸的三级线结构标准:

getGrid[x_, y_] := 
 FindDivisions[{x, y}, {10, 2, 5}] /. {r_, s_, t_} :> 
   Join[
     {#, Directive[Gray, Thick, Opacity[0.5]]} & /@ r, 
     {#, Directive[Gray, Opacity[0.5]]} & /@ Union[Flatten[s]], 
     {#, Directive[LightGray, Opacity[0.5]]} & /@ Union[Flatten[t]]
   ]


警告

我刚刚注意到,如果你在MMA中有这个:

然后将其复制到(只需ctrl-c ctrl-v),您将得到以下结果:

(maxY - minY)/stepy/(maxX - minX)/stepx  
这在数学上是不等价的。应该是这样的:

((maxY - minY)*stepx)/((maxX - minX)*stepy)

我在上面的代码中更正了这一点,但在我的计算机上正常工作的半天里,它被错误地发布了。我想提一下这个会很好。

我认为FindDivisions[]就是你想要的:

FindDivisions[{xmin,xmax},n] 查找大约n个“好”数字的列表,这些数字将xmin到xmax之间的间隔划分为等距部分


-1他已经得到了帧->真。他还使用网格线。框架边距不是一个选项Plot@Sjoerd看来我读他的答案太快了。但我的观点是,他确实需要将框架标记与网格线协调起来。我没有看到任何对FrameTicks的引用。好的,我删除了-1。你确定吗?我有一种预感,这可能是一种阴谋。@Sjoerd就在收到你关于FrameMargins的(合理的)批评之前,我尝试了FrameMargins和ImageMargins,发现前者不起作用,但后者起作用。因此,我修改了我最初的建议,改为推荐ImageMargins。我不能使用
FrameTicks->GetGrid
,但很有意思的是,这是否适用于某些情况。为了完整性,您可能需要插入需求[“ErrorBarPlots
”]。您是否希望网格线形成方形光栅?在这种情况下,您还必须使用
AspectRatio`.@Sjoerd C.de Vries:是的,您的权利。如果您想指定记号的位置,我建议使用。它的
CustomTicks
包远远优于内置功能,而且您不必编写自己的代码,这很容易出错,以设置自定义规范。@rcollyer:有趣的资源。显然,自定义网格线应该在下一版本的LevelScheme中。不过,我不知道它是否能够实现三个级别的样式。@Sjoerd C.de Vries:我尝试过这样的方法,但使用了
天花
Floor
函数却适得其反,因为在一些变量上,平均变化约为10^4,而其他变量为10^4。@Sjoerd C.de Vries:如果我设置
AspectRatio->(Max[y]-Min[y])(Max[x]-Min[x])
,并且变量大小的顺序是10,那么我认为它甚至可以工作(至少在我测试过的情况下)。但这并不是我想要做的。@Margus写出了你的第一条评论:检查我的更新;它应该适用于所有类型的数据范围。WRT评论#2:这行不通。如果y大x小怎么办?@Margus更改了我的更新,使用您的FromTo范围输入包含自动AspectRatio。@是否有人需要将此警告作为问题发布。如果您不这样做,我会的。+1我们能保证FindDivisions[]产生的滴答声与ticks->Automatic产生的滴答声相同吗?我在文档中找不到这个。如果不是,这不是一个保证的解决方案。但我猜FindDivisions[]会公开mma本身使用的例程。很好,我不知道这个。这就是为什么我认为mma的闪屏应该有一个当天的随机功能,以增加像这样的意外发现的数量。由于您的mm论文仍然不是Margus所要求的(正方形网格需要三个细分),我将在回答中使用您的代码进行更新。@Sjoerd“Assured”是一个强有力的词。我尝试了几个“最大-最小”设置,它的性能似乎与“滴答声->自动”相同。这显然是提供这一职能的用意。就当天的功能而言,我更喜欢严肃的文档重组,因为导航帮助几乎无法访问许多功能。@belisarius我希望在日志图中使用对数刻度,但FindDivisions[]似乎没有。至于第二句话:我同意帮助可能会更好,但我通常会找到解决办法。只要我知道有一个函数可以完成我的任务,我通常就能找到它。问题是知道suc
((maxY - minY)*stepx)/((maxX - minX)*stepy)
getTicks[x_, y_] := Flatten@FindDivisions[#, {10}] & /@ FromTo[x, y]
getGrid  [x_,y_] := FindDivisions[{x,y},{10,5}]/.
                          {r__,{s__}}:>Join@@{s,{#,{Gray,Thick}}&/@r}