How to best handle numerical formatting of tick values
In some code I am writing, sometimes I get ticks values like this
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]
and this makes it hard to format the plot to account for this extra space. Now, I set the image padding very large to have enough spac开发者_Python百科e for this extra value and it is wasted space.
btw, This problem only affects the y-values in my case.
I will show what I tried to solve this. But I am not happy with either method I have tried, and wanted to ask if there is a simpler way to solve this problem
This is what I tried to solve the problem
1) Use Ticks->fun
, but this is not working well, since it is hard to get the ticks formatted right, since the Bode plot y-values can change in units depending on options supplied, from dB to Absolute to Log10 to Linear and having to account for all of these and get the ticks right will not work.
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]
second solution:
Make the plot first, grab the ticks, use NumberForm
on them to format the y-values, and then make the plot with the new tick values:
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]]
The above method works, but it is slow, since I need to make BodePlot
2 times, and I find BodePlot
to be a little slow than normal plots, so I'd rather not have to do the above unless there is no other simpler solution.
Does any one see a simpler solution to this problem, may be one of them expert tricks?
thanks
Update 1:
I've used FindDivision[] given in the answer below like this to obtain the plot without the problem:
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]]
But this does not really help me in this case, as I do not know what divisions to do before hand unless I do the computation of the transfer function values over the range of the frequencies to find the minimum and the maximum, which ends up doing the whole computation twice, which I am trying to avoid.
FindDivisions
would work nice if one knows before hand the min/max of the plot range.
Update 8/13/2001
I got reply from WRI on this. Part of the response:
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 ?
After following the above, the problem is fixed! The plot now do not show the problem shown at the top of this post any more.
I am not sure what caused the preferences files problem, but at least now, if a new problem shows up, the above trick will be something I will try first.
Errrr ....
In 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]
In Mma 7 you can use 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]
Edit
You can use AbsoluteOptions[]
to solve the problem in your Edit calculating the plot only once:
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]}
]
精彩评论