如何最好地处理刻度值的数字格式

Nas*_*ser 2 wolfram-mathematica

在我写的一些代码中,有时我得到这样的刻度值

Clear[z];
hz = z/(z^2 - 0.6 z + 0.18);
tf = TransferFunctionModel[hz, z, SamplingPeriod -> 1];
p = BodePlot[tf, {0.01, 2 Pi},
    Frame -> False, PlotLayout -> "List", 
    ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}][[1]];
Show[p]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这使得很难格式化图表来解释这个额外的空间.现在,我将图像填充设置得非常大,以便为这个额外的值留出足够的空间,这是浪费的空间.

顺便说一句,这个问题只会影响我的y值.

我将展示我试图解决的问题.但我对我尝试的任何一种方法都不满意,并且想问一下是否有更简单的方法来解决这个问题

这就是我试图解决的问题

1)使用Ticks->fun,但这不能正常工作,因为很难正确格式化滴答,因为波特图y值可以根据提供的选项以单位改变,从dB到绝对到Log10到线性并且必须考虑到对于所有这些并获得正确的滴答将无法正常工作.

Clear[z];
fun[min_, max_] := 
 Module[{}, 
  Join[Table[i, {i, Ceiling[min], Floor[max]}], 
   Table[j, {j, Round[min], Round[max - 1], 1}]]]

hz = z/(z^2 + 0.5);
tf = TransferFunctionModel[hz, z, SamplingPeriod -> 1];
p = BodePlot[tf, {0.01, 2 Pi}, Frame -> False, PlotLayout -> "List", 
    ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear","Degree"}}, 
    Ticks -> fun][[1]];
Show[p]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

二解决方案:

首先绘制图,抓住刻度,使用NumberForm它们来格式化y值,然后使用新的刻度值创建绘图:

Clear[z];
hz = z/(z^2 - 0.6 z + 0.18);
tf = TransferFunctionModel[hz, z, SamplingPeriod -> 1];
p = BodePlot[tf, {0.01, 2 Pi}, Frame -> False, PlotLayout -> "List", 
    ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}][[1]];
ticks = Ticks /. AbsoluteOptions[p, Ticks];

ticks[[2, All, 1 ;; 2]] = 
  If[NumericQ[#[[2]]], {#[[1]], NumberForm[#[[2]], 3]}, #] & /@ 
   ticks[[2, All, 1 ;; 2]];

BodePlot[tf, {0.01, 2 Pi}, Frame -> False, PlotLayout -> "List", 
  ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}, 
  Ticks -> {ticks, Automatic}][[1]]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

上面的方法有效,但速度很慢,因为我需要做BodePlot2次,而且发现BodePlot比普通图慢一点,所以除非没有其他更简单的解决方案,否则我宁愿不必做上述事情.

有没有人看到这个问题的更简单的解决方案,可能是其中一个专家技巧?

谢谢

更新1:

我已经在下面的答案中使用FindDivision []这样来获得没有问题的情节:

BodePlot[tf, {0.01, 2 Pi}, Frame -> False, PlotLayout -> "List", 
  Ticks -> {{FindDivisions[{0, 10}, 10], N@FindDivisions[{0, 2}, 10]},Automatic}, 
  ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}][[1]]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是在这种情况下这并没有真正帮助我,因为我不知道除了我在频率范围内计算传递函数值以找到最小值和最大值之前要做什么划分,这最终会做整个计算两次,我试图避免.

FindDivisions 如果事先知道绘图范围的最小值/最大值,那将会很好用.

更新8/13/2001

我得到了WRI的回复.部分回复:

Close Mathematica. Hold Control and Shift buttons while launching
 Mathematica. Keep holding the buttons down till Mathematica is fully up
 (the welcome screen shows up.)

 Try your plot again. How does this look ?
Run Code Online (Sandbox Code Playgroud)

完成以上操作后,问题就解决了!该情节现在不再显示此帖子顶部显示的问题.

我不确定导致首选项文件问题的原因,但至少现在,如果出现新问题,我将首先尝试上述技巧.

Dr.*_*ius 5

Errrr ....

在Mma 8:

Clear[z];
hz = z/(z^2 - 0.6 z + 0.18);
tf = TransferFunctionModel[hz, z, SamplingPeriod -> 1];
p = BodePlot[tf, {0.01, 2 Pi}, Frame -> False, PlotLayout -> "List", 
    ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}][[1]];
Show[p]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在Mma 7中你可以使用FindDivisions[]:

p = BodePlot[tf, {0.01, 2 Pi}, 
    Frame -> False, PlotLayout -> "List", 
    Ticks -> {Automatic, FindDivisions[{0, 10}, {11, 10, 2}]}, 
    ScalingFunctions -> {{"Linear", "Absolute"}, {"Linear", "Degree"}}][[1]];
Show[p]
Run Code Online (Sandbox Code Playgroud)

编辑

您可以使用" AbsoluteOptions[]编辑" 在计算一次绘图时解决问题:

p = BodePlot[tf, {0.01, 4 Pi}, 
             Frame -> False, PlotLayout -> "List", 
             ScalingFunctions -> {{"Linear", "Absolute"}, 
                                  {"Linear", "Degree"  }}];

pr = (AbsoluteOptions[p, PlotRange] /. Rule[x_, y_] -> y);

Show[First@p, 
     Ticks -> {N@FindDivisions[pr[[1, 1, 1]],10],
               N@FindDivisions[pr[[1, 1, 2]],10]}
]
Run Code Online (Sandbox Code Playgroud)