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

时间:2011-07-29 03:05:08

标签: 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]

enter image description here

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

btw,此问题仅影响我的y值。

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

这是我试图解决问题的方法

1)使用Ticks->fun,但效果不佳,因为很难正确格式化滴答,因为波特图y值可以根据提供的选项以dB为单位改变,从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]

enter image description here

第二个解决方案:

首先绘制图,抓住刻度线,使用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]]

enter image description here

以上方法有效,但速度很慢,因为我需要进行BodePlot 2次,而我发现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]]

enter image description here

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

如果事先知道绘图范围的最小值/最大值,那么

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 ?

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

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

1 个答案:

答案 0 :(得分: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]

enter image description here

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

修改

您可以使用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]}
]