Here is a simple illustration of the problem and
> inconsistency, using just the first few points in
> Tennessee's plot and a few lines from his script. With a
> log scale for y, the Agg backends are leaving gaps (breaking
> the line) at the points where y==0; the PS and SVG backends
> are removing those points, but *not* breaking the line. I
> think the Agg behavior is much better. But maybe it would
> be better yet to raise an exception, forcing the user to
> deal with the error explicitly. For example, the user might
> want to change the zero values to a very small number, and
> then explicitly set the y range to exclude the small
> numbers. This is illustrated in the second subplot.
This issue has a long history, which I'll summarize here. In the old
days, we raised an exception when non-positive numbers were passed to
log plotting. Most people found this objectionable, and prefer to see
the valid points plotted rather than nothing (though a warning would
be nice). This is what matlab does. I needed to make some
architectural changes to support this, because the transformations
happened in the lines class which passed the transformed data to the
backend.
I looked into filtering the data in the lines class (basically what
you did for ma data) but did not think it would be fast enough,
because we potentially would have had to create a lot of line
segments.
So I changed the backend API and modified draw_lines to take the
transformation as an argument. Then the backend can do the following
(eg _backend_agg)
if (needNonlinear)
try {
mpltransform->nonlinear_only_api(&thisx, &thisy);
}
catch (...) {
moveto = true;
continue;
}
Ie if there is a nonlinear transformation that raises an exception,
the path state is changed from lineto to moveto. This is very fast,
at least an order of magnitude faster than trying to compute the
segments at the python level I suspect.
At the same time I introduced some optimizations for marker drawing
with a new backend method called draw_markers that also does the
transformations in the backend. This made marker drawing up to 25
times faster (we used to draw every marker as a separate function call
in lines.py)
We decided to support both old and new style APIs in the "transition
period" which made it easy for other backends to do ..... nothing. So
that is why the other backends haven't implemented this feature yet.
Steve worked on it a bit for Cairo and Darren and I both did for PS
but never got a working product. You can see the attempt in
backend_ps _draw_markers method (underscore hidden) and in
backend_cairo's draw_markers_OLD method. There was extensive
discussion on this list with the API and implementation details so
just search for draw_markers if you are interested.
So the backend is now in what I call a schizophrenic state, in two
ways.
1) some backends use the old and some use the "newstyle" API
2) Even in the newstyle API, some methods do the transformation in
the front end (draw_rectangle) and some in the backend
(draw_markers).
There is a need to simplify, unify and rationalize this API, but since
it mostly works, there has not been a lot of pressure to do so. And
it would break a lot of backends that may not be actively maintained.
A modest short term goal should be to get the newstyle draw_lines and
draw_markers working for the PS backend, both to fix this log problem
and because it is faster and potentially much smaller in terms of PS
file sizes. Something for a rainy day.
JDH