Wolfram mathematica 自适应网格线
我想使用网格线在2d图形上创建的效果,以显示多变量函数如何依赖于一个变量。不同变量的尺度差异很大,因此我的天真方法(我以前使用过)似乎不起作用 我目前拥有的示例: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[
<< 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}