John Hunter wrote:
"Phil" == Phil Erickson <pje@...101...> writes:
> Hi all, I am really enjoying working with matplotlib and
> hats off to an excellent effort.
> I have done a cursory search of the mailing list archives
> but didn't find the answer to a practical question that I
> ran into in MATLAB all the time (which is where I'm coming
> from in terms of familiarity).
> Suppose I have an array to plot, and I want to exclude
> certain points from being plotted. In MATLAB, I would set
> the y vector points I wanted excluded to "NaN" and then the
> plot routine would draw connected lines up to the point
> before the excluded one, skip the bad/not wanted point, and
> then continue drawing lines beginning at the next point.
> How does one accomplish that using matplotlib? This
> actually comes up quite often in our radar work here, in
> cases where we are making log plots of vectors which may
> contain zeros.
What matplotlib currently does is simply ignore non-positive data with
an approach along the lines of
ind = nonzero(y > 0)
validy = take(y, ind)
Just to make sure I'm understanding you properly, that's not a good
solution for you because you want to the gap in the connected line
where the complex (y<=0) points are. Is this right?
That's right. In our field, we often have data sets which have to be culled before plotting for points which might fail some sanity test like excessive variance, etc. I'm sure other science data sets have a similar requirement. For ease of use, I would definitely not want to have to break up my plot task into multiple lines myself by segmenting the incoming data, but rather have the method do it based on some signal value in the data.
In fact, the plots that I was trying to make were of a quantity which needs to be expressed in dB, which is
10 * log10(y)
So the problem is actually a bit more general, in that just calling semilogy() would make a plot of log10(y) which is not quite the same. For my needs, I have been using
plot(x, 10 * ProtectedLog(y))
"Calculate log10() but protect against non-positives."
zeroIndex = find(a <= 0.0)
b = array(a)
for index in zeroIndex:
# ideally we would use whatever value will
# signal a non-plotted point; 1e-30 is
b[index] = 1e-30
c = log10(b)
Therefore, both plot() and semilogy() would have to pay attention to a special signal value.
What you describe is certainly possible but would impose a performance
hit that depends on the number of separate connected lines that had to
be constructed. Eg, semilogy could find the non-positive indices and
create the line segments appropriately.
Indeed, but your line drawing functions seem to be fast enough that maybe this isn't an issue.
As for NaN, I'm not an expert here. As far as I understand, there is
no support for it in Numeric but there is in numarray. Look for basic
numarray support in the next release.
All our code uses Numeric, so we have inertia working against us NaN is for me just a value that I know MATLAB pays attention to when plotting. If you had another way to put a value in, I could use that and all would be well.
Unfortunately, it seems Python has some trouble with IEEE standard values such as positive/negative infinity and NaNs. There seems to be a pure Python package which would handle IEEE 754 standard NaN values at
which perhaps might be a way to go. The author has also made a request that this functionality be included in further Python releases.
Phil Erickson email: pje@...101...
Atmospheric Sciences Group WWW: http://www.haystack.mit.edu
MIT Haystack Observatory voice: 781 981 5769
Westford, MA 01886 USA fax: 781 981 5766
Public key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x54878872