I just completed some open-heart surgery on the path simplification code 
to resolve this and other issues.  Though the integer overflow bug is on 
the maintenance branch, the proper solution was large enough and risky 
enough that I have only committed it to the development trunk.

Before, the path simplification code jumbled a number of discrete steps 
together in the code:

   1. Nan (nonfinite) handling
   2. Clipping
   3. Quantization
   4. Simplification


This has been rewritten (see path_converters.h) so each step is handled 
by a separate iterator class that can be independently switched on-and-off.

This refactoring made it much easier to rewrite the clipping algorithm 
to actually bisect line segments at the figure boundary, rather than (as 
before) simply removing vertices after crossing outside the boundary.

Additionally, nan-value-handling was formerly handled in both Python and 
C++, which was both double the maintenance and slower in Python.  Now, 
the C++ version of the entire pipeline has been exposed to Python, so we 
have a single (and faster) code path to debug.  (Note that whereas it 
behaves as an iterator in C++, it actually writes to a new array in the 
Python-wrapped version to avoid lots of tiny Python function calls).  
All backends now use this pipeline (through the use of 
Path.iter_segments). 

A side effect of this is that whereas before Python backends were forced 
to get clipping and simplification together, they now have independent 
control.  This fixes two long-standing bugs in non-Agg backends:

   1.   large values would cause integer overflow (causes the lines to
      appear to go in the wrong direction)
   2.   clipping should be turned off for filled regions, but that
      wasn't previously possible without also losing simplification


Lastly, the threshold of angular similarity below which simplification 
will start removing vertices has been exposed to the user as an rcParam 
(path.simplify_threshold).  It can also be set on an individual basis to 
any Path object.

The one remaining major piece is to get the native Cocoa backend to 
support this infrastructure.  Right now, it reimplements its own 
nan-handling and doesn't perform any of the other steps.  This will 
probably require some code compiled in C++ but exported as C to make it 
accessible to Objective-C.  The general roadmap is in "cleanup_path" in 
_path.cpp.  I'm happy to help with this, but without a Mac, it will be 
hard to compile and test these changes.

I've looked through all the backend_driver images, and everything seems 
ok, but let me know if you see any strangely drawn paths etc.

Cheers,
Mike



Michael Droettboom wrote:
> Okay -- I think I've at least narrowed it down to a cause.  Agg uses 
> fixed-point arithmetic to render at the low-level -- by default it uses 
> 24.8 (i.e. 24 integer bits and 8 fractional bits).  Therefore, it can 
> only handle pixel coordinates in the range -2^23 to 2^23.  Both of the 
> provided examples, after the data has been scaled, draw outside of this 
> range, which results in integer overflow, hence things going in the 
> wrong direction etc.
>
> We could change the fixed point in agg_basics.h, but I hesitate to do 
> so, as it's at the expense of fine detail.  We could possibly move to 
> 64-bits, but I'm not sure how easy that would be, or what the impact 
> might be on 32-bit platforms.
>
>     
> //----------------------------------------------------poly_subpixel_scale_e
>     // These constants determine the subpixel accuracy, to be more precise,
>     // the number of bits of the fractional part of the coordinates.
>     // The possible coordinate capacity in bits can be calculated by 
> formula:
>     // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
>     // 8-bits fractional part the capacity is 24 bits.
>     enum poly_subpixel_scale_e
>     {
>         poly_subpixel_shift = 8,                      
> //----poly_subpixel_shift
>         poly_subpixel_scale = 1<<poly_subpixel_shift, 
> //----poly_subpixel_scale
>         poly_subpixel_mask  = poly_subpixel_scale-1,  
> //----poly_subpixel_mask
>     };
>
>
> One thing I will look into is whether the line simplification algorithm 
> can be extended to actually clip the lines when they go outside of the 
> image range.  At the moment, it does some work to reduce the number of 
> points outside of the image, but it always draws at least one point 
> outside at its original location.  It looks like Agg has some of the 
> pieces necessary to do this -- whether it's feasible to integrate that 
> into our existing line simplification algorithm remains to be seen.
>
> Mike
>
>
> Michael Droettboom wrote:
>   
>> Thanks for this.
>>
>> I believe both of these examples illustrate a shortcoming in Agg when 
>> the distance between two points on either end of a line is too great.
>>
>> I'll do some digging around and see what may be causing this and if any 
>> limits can be adjusted -- I may not get to this today, however.
>>
>> Mike
>>
>> João Luís Silva wrote:
>>   
>>     
>>> Jan Müller wrote:
>>>   
>>>     
>>>       
>>>> Hi,
>>>>
>>>> The simple code snippet at the end of this mail should plot a single line. 
>>>>
>>>>     
>>>>       
>>>>         
>>> I can confirm this bug on Ubuntu running matplotlib svn revision 6827. 
>>> However I think it doesn't have to do with the log-scale but with the 
>>> big variations on the x-scale and the custom xscale. I've reproduced a 
>>> similar behavior with the following script (pan and zoom to see the 
>>> buggy behavior).
>>> --------------------
>>>
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>>
>>> x = np.array([1.0,2.0,3.0,1.0E5,2.0E5])
>>> y = np.arange(len(x))
>>> plt.plot(x,y)
>>> plt.xlim(xmin=2,xmax=6)
>>> plt.show()
>>>
>>> --------------------
>>>
>>> Best Regards,
>>> João Silva
>>>
>>>
>>> ------------------------------------------------------------------------------
>>> This SF.net email is sponsored by:
>>> SourcForge Community
>>> SourceForge wants to tell your story.
>>> http://p.sf.net/sfu/sf-spreadtheword
>>> _______________________________________________
>>> Matplotlib-devel mailing list
>>> Matplotlib-devel@lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>>>   
>>>     
>>>       
>>   
>>     
>
>   

-- 
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA


------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to