Skip to content

Keyword *interpolation* behaving improperly while saving to SVG with **savefig()** #12065

Closed

Description

@dabana

Bug report

Bug summary

When saving an interpolated rbga image to SVG format, the output depends whether the keyword interpolation as been omitted or it has been put to none (interpolation="none"). This should not be the case. It should produce an UN-interpolated image in both case. We do not see this behavior with the other formats, PNG for instance.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

fig, (axl, axr) = plt.subplots(1, 2)
# full green image
img = np.zeros((5, 5, 4))
img[...,1] = np.ones((5, 5))
# transparent above main diagonal
img[...,3] = np.tril(np.ones((5, 5), dtype=np.uint8))

axl.set_title('with keyword\ninterpolation="none"')
axr.set_title('WITHOUT keyword\ninterpolation')
axl.imshow(img, interpolation="none")
axr.imshow(img)

plt.savefig('interp_alpha_svg.svg')
plt.savefig('interp_alpha_png.png')

Actual outcome

Github does not support SVG so here is my description. The left image, with interpolation="none", looks interpolated (smoothed edges), but the right image, WITHOUT the interpolation keyword, has sharp edges.

Expected outcome

This is the output you get when format is PNG.

interp_alpha_png

Matplotlib version

  • Operating system: Ubuntu 16.04 Bash on Windows10
  • Matplotlib version: 3.0.0rc1.post186+g5e01393
  • Matplotlib backend (print(matplotlib.get_backend())): agg
  • Python version: 3.5.2
  • Jupyter version (if applicable):
  • Other libraries:
    matplotlib installed from source

Activity

  1. anntzer commented on Sep 7, 2018

    @anntzer
    Contributor

    I think this is basically an instance of #10112: the uniniterpolated image is stored as a big 5x5 image and svg renderers interpolate it by default; the non-interpolated image is upsampled (in nearest mode) to a much larger number of pixels.

  2. dabana commented on Sep 7, 2018

    @dabana
    ContributorAuthor

    Okai so if I understand correctly, if we want to fix this issue we need to make sure that a large UPsampled image gets sent to the SVG renderer with interpolation="none" as well as WITHOUT the interpolation keyword (which is already the case).

  3. anntzer commented on Sep 7, 2018

    @anntzer
    Contributor

    No, we want to tell the svg renderer not to perform resampling itself, as explained in #10112.

  4. dabana commented on Sep 7, 2018

    @dabana
    ContributorAuthor

    Just so I get this clear, specifying interpolation="none" and omitting interpolation behaving differently IS the intended behavior?

  5. anntzer commented on Sep 7, 2018

    @anntzer
    Contributor

    Good point, that I don't know...

  6. dabana commented on Sep 7, 2018

    @dabana
    ContributorAuthor

    IF "specifying interpolation=none" and "omitting interpolation" behaving differently IS the intended behavior

    THEN, oh well... close this issue...

    OTHERWISE we have two options:

    A) We should make sure that a NON-sampled image gets sent to the SVG renderer with interpolation="none" (which is already the case) as well as WITHOUT the interpolation keyword. That way the SVG render takes care of doing whatever it wants.

    B) We should make sure that the SVG renderer always does a descent job by sending it an UP-sampled image with interpolation="none" as well as WITHOUT the interpolation keyword (which is already the case).

    A or B is the question now...

  7. dabana commented on Sep 7, 2018

    @dabana
    ContributorAuthor

    I vote for B

  8. ImportanceOfBeingErnest commented on Sep 7, 2018

    @ImportanceOfBeingErnest
    Member

    Just that we know what the issue is, here is the output of the code when the svg is opened in inkscape 0.91:

    image

    (Maybe worth noting that inkscape 0.49 shows no difference between the two subplots)

  9. ImportanceOfBeingErnest commented on Sep 7, 2018

    @ImportanceOfBeingErnest
    Member

    Equally worth noting that there is a difference between None and "none" (None is the image.interpolation rc parameter, which defaults to "nearest").

    image

    The interpolation_methods demo states:

    For the Agg, ps and pdf backends, interpolation = 'none' works well when a big image is scaled down, while interpolation = 'nearest' works well when a small image is scaled up.

    So apparently some difference is expected between the two.

  10. dabana commented on Sep 8, 2018

    @dabana
    ContributorAuthor

    From the imshow() documentation:

    interpolation : string, optional, default: None
    Acceptable values are 'none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos'

    If interpolation is None, default to rc image.interpolation. See also the filternorm and filterrad parameters. If interpolation is 'none', then no interpolation is performed on the Agg, ps and pdf backends. Other backends will fall back to 'nearest'.

    So it IS the intended behavior. In the doc, should we specify:

    1. that the SVG backend will not perform any interpolation either using interpolation = 'none'
    2. that rc image.interpolation is the same as 'nearest'
    3. that SVG renders (such as browsers) might perform interpolation on SVG images.
  11. timhoffm commented on Sep 9, 2018

    @timhoffm
    Member

    The docstring has already changed a bit in the current master:
    https://matplotlib.org/devdocs/api/_as_gen/matplotlib.axes.Axes.imshow.html

    Issue 2 is already handled. 1 an 3 remain open. You are welcome to provide a PR to clarify the SVG handling.

  12. added this to the v3.1 milestone on Sep 10, 2018
  13. added a commit that references this issue on Apr 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions