6

I am trying to fix the Phase plot part of BodePlot, as it does not wrap correctly. And there is no option that I can use to tell it to wrap.

So, instead of doing the full plot myself, (I can do that if I have to) I am thinking of first making the BodePlot, grab the data points, do the wrapping on the data (once I get the x,y data, the rest is easy), then I need to put the new list of points back into the plot, and then use Show to display it.

The part I am stuck at, is extracting the points from FullForm. I can't get the correct Pattern to do that.

This is what I go to so far:

hz=z/(z^2-z+0.3);
tf=TransferFunctionModel[hz,z,SamplingPeriod->2];
phasePlot=BodePlot[tf,{0.001,2 Pi},
       ScalingFunctions->{Automatic,{"Linear","Degree"}},PlotLayout->"List"][[2]]

enter image description here

You see how it does not wrap at 180 degrees. It is more common in dsp that Bode phase plot wraps. Here is what it 'should' look like:

enter image description here

So, this is what I did:

 FullForm[phasePlot]
Graphics[List[
  List[List[], List[], 
   List[Hue[0.67, 0.6, 0.6], 
    Line[List[List[0.0010000243495554542, -0.2673870119911639], 
      List[0.0013659538057574799, -0.36521403872250247], 
      List[0.0017318832619595053, -0.46304207336414027],
      ....

I see the data there (the x,y) But how to pull them out? I tried this:

  Cases[FullForm[phasePlot], List[x_, y_] -> {x, y}, Infinity];

But the above matches in addition to the list of point, other stuff that I do not need. I tried many other things, but can't get only the list of points out.

I was wondering if someone knows how to pull only the (x,y) points from the above plot. Is there a better way to do this other than using FullForm?

Thanks

Update:

I just find a post here which shows how to extract data from plot. So I used it:

   points = Cases[Normal@phasePlot, Line[pts_] -> pts, Infinity]
Community
  • 1
  • 1
Nasser
  • 12,849
  • 6
  • 52
  • 104
  • I think you are misunderstanding `FullForm`. See my comments on David's answer. (I just noticed that you also used `FullForm` in the question.) – Szabolcs Jul 27 '11 at 12:00
  • 1
    I do not have Mma 8 so I don't know about BodePlot. However, Andrew Moylan (see [here](http://stackoverflow.com/questions/5287817/the-best-way-to-construct-a-function-with-memory/5288314#5288314)) has pointed out that `EvaluationMonitor`, together with Sow/Reap, may be used to 'cleanly' extract data points from `Plot`. This can be useful. For example, the following evaluates to True. `Sort /@ Last@ Reap[Plot[Sin[x], {x, 0, 4 Pi}, EvaluationMonitor :> Sow[{x, Sin[x]}]]] == Cases[Plot[Sin[x], {x, 0, 4 Pi}], x_Line :> First@x, Infinity]` – 681234 Jul 27 '11 at 12:50

2 Answers2

6

You could do try nesting the replacement rules, for example

phase2 = phasePlot /. 
    Line[a_] :> (Line[a] /. {x_?NumericQ, y_?NumericQ} :> {x, Mod[y, 360, -180]});
Show[phase2, PlotRange -> {Automatic, {-180, 180}}, FrameTicks -> Automatic]

Output:

BodePlot with wrapping

Heike
  • 24,102
  • 2
  • 31
  • 45
3

The list you are looking for appears to be wrapped by Line[], and it seems to be the only case in your plot. So you could use

Cases[phasePlot, Line[list_] :>  list, Infinity]

Edit: When I posted my response, the page refreshed and I saw that you came across precisely what I had proposed. I'll leave my response posted here anyway.

Edit2: Szabolics pointed out that FullForm[] has no effect, so I removed it from my original posting.

DavidC
  • 3,056
  • 1
  • 20
  • 30
  • 1
    `FullForm` is for printing the expression with a special formatting, it does not do anything useful in this `Cases`. What you *might* need is `Normal` to expand any `GraphicsComplex` objects. – Szabolcs Jul 27 '11 at 11:53
  • 3
    To clarify: In general, `FullForm` or any of the `*Form` functions never do any structural modification on the expression. They simply affect the way it's printed. What you see and what the kernel sees are not always the same. – Szabolcs Jul 27 '11 at 11:58
  • @Szabolics. Thanks for the clarification about `FullForm`. I now dropped it from my posting. – DavidC Jul 27 '11 at 13:35