Skip to content

Incorrect PDF output with rasterized=True #3371

Open

Description

@astrofrog

The following example demonstrates an issue with the PDF output when setting rasterized=True:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
z = np.random.random((100000, 3, 2))
lc = LineCollection(z, rasterized=True, alpha=0.01, color='k')
ax.add_collection(lc)
fig.savefig('test.png')
fig.savefig('test.pdf')

The PNG output is:

test

The PDF output (converted to PNG, looks the same), is:

test_pdf

For some reason, the PDF output appears gray not black in the center.

Activity

  1. added this to the milestone on Aug 15, 2014
  2. tacaswell commented on Aug 15, 2014

    @tacaswell
    Member

    Confirmed on close-to-1.4.0.

    We seem to be having a run on alpha-related issues recently (#3343 )

  3. tacaswell commented on Aug 15, 2014

    @tacaswell
    Member

    And I milestoned this as 1.5 because I suspect that this will require a re-work of how we deal with alpha, if it is a small patch it should go at 1.4.x.

  4. mdboom commented on Aug 25, 2014

    @mdboom
    Member

    Looks like a pre- vs. post-alpha issue to me (which has always been tricky with PDF).

  5. astrofrog commented on Sep 11, 2014

    @astrofrog
    ContributorAuthor

    @tacaswell @mdboom - thanks. Just out of interest, do you think there are any workarounds for this issue, other than simply not using the rasterized mode?

  6. astrofrog commented on Sep 11, 2014

    @astrofrog
    ContributorAuthor

    For example, is there any way that I can access the actual data values from the rasterized array? If so, I could then just try showing it with imshow and adjust the levels.

  7. jenshnielsen commented on Sep 11, 2014

    @jenshnielsen
    Member

    You could try PDFs from the Cairo backend

  8. astrofrog commented on Oct 2, 2014

    @astrofrog
    ContributorAuthor

    Using cairo as the backend actually results in the rasterized argument getting ignored, which I guess could be considered a bug?

  9. mdboom commented on Oct 2, 2014

    @mdboom
    Member

    The cairo backend has never supported rasterization. Not a bug, so much as an unimplemented feature.

    I've spent some time investigating this. It doesn't appear to be an issue with how the PDF file is put together. If you modify the figure so it is on a transparent background, write to a PNG, and then use a tool like the GIMP to superimpose it back on a white background, you'll get something that looks like the PDF output (greyish).

    My best guess at this point is that it's somehow a difference in how Agg blends against a transparent background vs. a white background. Still plugging away...

  10. mdboom commented on Oct 2, 2014

    @mdboom
    Member

    I think my hunch is proven by the math. Here's a little example script that simulates alpha blending exactly the way Agg does it in blender_rgba::blend_pix:

    import numpy as np
    
    
    def blend(fg, bg):
        fge = np.asarray(fg, np.uint16)
        bge = np.asarray(bg, np.uint16)
        a = fge[3]
    
        result = fge * a + bge * (255 - a)
    
        result >>= 8
    
        alpha = bge[3]
        result[3] = (alpha + a) - ((a * alpha + 255) >> 8)
    
        return np.asarray(result, np.uint8)
    
    
    def blend_many(start, color):
        bg = start
    
        for i in range(1000):
            bg = blend(color, bg)
    
        print(bg)
        print
    
    blend_many(np.array([0, 0, 0, 0], np.uint8), np.array([0, 0, 0, 2], np.uint8))
    blend_many(np.array([255, 255, 255, 255], np.uint8), np.array([0, 0, 0, 2], np.uint8))
    

    output:

    Onto transparent:
    [  0   0   0 129]
    
    Onto white:
    [  0   0   0 255]
    

    So, when blending a low-transparency pixel onto a transparent image, it eventually converges around "half" grey, whereas on white it converges on true black.

    I'm not sure what the solution is here, but there must be a standard graphical method around this problem somewhere...

  11. tacaswell commented on Oct 2, 2014

    @tacaswell
    Member

    I suspect the fix is along the lines of #2479 setting alpha to 1 instead of 0.

  12. tacaswell commented on Oct 2, 2014

    @tacaswell
    Member
    blend_many(np.array([255, 255, 255, 0], np.uint8), np.array([0, 0, 0, 2], np.uint8))

    also converges to [0, 0, 0, 129].

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.collections import LineCollection
    
    fig = plt.figure()
    fig.patch.set_color([0, 0, 0, 0])
    
    ax = fig.add_subplot(1,1,1)
    ax.patch.set_color([0, 0, 0, 0])
    z = np.random.random((100000, 3, 2))
    lc = LineCollection(z, rasterized=True, alpha=0.01, color='k')
    ax.add_collection(lc)
    fig.savefig('test.png', transparent=True)
    fig.savefig('test.pdf')

    will generate a png that is only gray in the middle.

    On consideration, doing the rasterization onto a transparent layer is rather essential to this whole scheme working.

  13. mdboom commented on Oct 2, 2014

    @mdboom
    Member

    Further data point: The maintained fork of Agg here (http://sourceforge.net/p/agg) appears to be doing the blending completely differently. The solution there still doesn't seem to yield correct results, but upgrading to this fork may be a worthwhile experiment.

  14. 13 remaining items

  15. petehuang commented on Jan 12, 2017

    @petehuang
    Contributor

    Reconfirming on 1.5.3

  16. tacaswell commented on Jan 16, 2017

    @tacaswell
    Member

    @joferkington The color mapping issues is fixed in 2.0.

  17. modified the milestones: , on Jan 16, 2017
  18. jklymak commented on Jan 18, 2018

    @jklymak
    Member

    This is still a bug on Master (2.1.2).

  19. anntzer commented on Jan 21, 2019

    @anntzer
    Contributor

    mplcairo (master) now supports floating point surfaces (and fixes this issue, as well as #4322)... if you have the courage to build it and use it with cairo master (cairo master has floating point surface support, but that's not in a released version of cairo yet).

    Edit: cairo 1.17.2 has been released with this feature.

  20. github-actions commented on Mar 5, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  21. github-actions commented on Mar 6, 2024

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  22. added
    keepItems to be ignored by the “Stale” Github Action
    and removed
    status: inactiveMarked by the “Stale” Github Action
    on Mar 6, 2024
  23. anntzer commented on Mar 6, 2024

    @anntzer
    Contributor

    This essentially depends (I think?) on upgrading to agg svn (per the discussion above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions