gpt4 book ai didi

wolfram-mathematica - 自适应网格线

转载 作者:行者123 更新时间:2023-12-04 08:14:30 27 4
gpt4 key购买 nike

我想用网格线创建millimeter graphing paper的效果在二维图形上,显示多变量函数如何依赖于 1 个变量。不同变量的尺度差异很大,所以我的幼稚方法(我以前使用过)似乎不起作用。

我目前拥有的示例:

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

两者 FromTo (我想在框架中留下 5% 的边距)和 GetGrid不完全按照我希望的方式工作。

在某些轴上,变量相差 10 的许多阶数。而且我不希望一个轴比其他轴多 10 个网格线的阶数。最重要的是,我希望网格线与刻度线对齐。

样本数据:
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]), 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"
]

会导致:

enter image description here

而我天真的 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}]
]



如何使 GridLines 与刻度对齐?

编辑:与
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
]

我可以得到:

enter image description here

这要好得多。但我想移动网格而不是刻度线。

编辑:@Sjoerd C. de Vries

您的解决方案完成了我想要存档的工作。我还注意到,如果我取样本数据的前 5 个元素,则绘图将是(元素已排序并添加回归线)。
enter image description here

注意最左边的元素就像离网。

最佳答案

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

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"]

enter image description here

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

enter image description here

最终更新(我希望)

这使用 FindDivisions 作为 suggested by belisarius .但是,我按照 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]]
]


getAspect[{{minX_, maxX_}, {minY_, maxY_}}] :=
Module[{stepx, stepy},
stepx = (#[[2]] - #[[1]]) &@FindDivisions[{minX, maxX}, 10];
stepy = (#[[2]] - #[[1]]) &@FindDivisions[{minY, maxY}, 10];
((maxY - minY)/stepy)/((maxX - minX)/stepx)
]

警告!!!

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

enter image description here

然后将其复制到 SO(只需 ctrl-c ctrl-v),您会得到:
(maxY - minY)/stepy/(maxX - minX)/stepx  

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

我在上面的代码中更正了这个问题,但是在我的电脑上正常工作时它已经发布了半天。觉得提一下就好了。

关于wolfram-mathematica - 自适应网格线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5664937/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com