5

Trying to answer a recent question I've come across a strange behavior with stem. Try this:

x = [1+j 2-j 3+j 4-j];
stem(x)

On my Matlab version (2010b) this plots the imaginary part of x, not the real part as I expected. On the contrary,

stem(1:length(x),x)

plots the real part of x, which is consistent with the behavior of plot(1:length(x),x).

Can you think of any reason why stem(x) plots the imaginary part of x instead of the real part? Specially when stem(1:length(x),x) does plot the real part. Or should we conclude it's a bug?

Community
  • 1
  • 1
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147

1 Answers1

3

As far as I can tell, this is partially correct behavior. When you input an imaginary, the real and imaginary components are treated as x and y value pairs (i.e. in xychk.m, x = real(y); y = imag(y);). So this explains why the imaginary component is on the y-axis.

However, when you input x-axis values with a second argument, it gets the x-axis values from the first input argument and treats the real part of y as the y-axis data. Specifically, when stem(1:length(x),x) is called, stem.m creates a specgraph.stemseries with complex values provided for YData. However, it seems that the YData cannot hold complex data and the real part is kept. This feels like a bug, but it appears to be by design if the plot docs apply to stem.

As stated by MathWorks about the plot command (apparently applies to stem):

When the arguments to plot are complex (i.e., the imaginary part is nonzero), All MATLAB® graphics functions ignore the imaginary part except when plot is given a single complex data argument. For this special case, the command produces a plot of the real part versus the imaginary part. Therefore,

plot(Z)

where Z is a complex vector or matrix, is equivalent to

plot(real(Z),imag(Z))

There does appear to be a bug in stem and stairs pointed out by David and Daniel R., where the proper XData is not set with the first (single-argument) syntax. The source of the bug in stem.m seems to be here:

if hasXData
    xdata = {'XData', datachk(x(:,k))};
end

The problem is that hasXData is set above by hasXData = nargs ~= 1;. I think this should perhaps be something like:

hasXData = nargs ~= 1 || ~isreal(args{1});
Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • 1
    But if you do `x = [1+j 2-j 3+j 10-j];` then the x-axis points are 1, 2, 3 and 4, not 1, 2, 3 and 10, and `stem(x)` produces a different graph to `stem(real(x),imag(x))`. – David Nov 13 '13 at 01:25
  • For `stem([1+i,3,5-i])` it returns a plot with `(1,1)(2,0)(3,-1)` – Daniel Nov 13 '13 at 01:26
  • @David (and Daniel R.) Interesting observations. I'd agree that is a bug and I made a guess as to where it comes from in `stem.m`. Still, it seems clear why the imaginary component ends up on the y-axis in the single-input syntax. – chappjc Nov 13 '13 at 01:48
  • @chappjc Of course! How didn'y I think about it? `plot(x)` with `x` complex also plots imag vs. real. Lesson learned: don't choose too simple things such as 1:4 as examples – Luis Mendo Nov 13 '13 at 09:47