Skip to content

imshow interpolation generating artifacts #9961

Closed

Description

@arthur00

Bug report

Bug summary

When interpolating a 2D heatmap on Windows, I get colored artifacts drawn over the 'bad' points. I am using LogNorm for normalization. I suspect it has something to do with the masked values caused by having 0s in a LogNorm. I set then to white with set_bad() function. On Linux, the interpolation looks entirely different (the white areas are not interpolated) and no artifacts can be seen.

I've also tried different interpolating methods, all of them seem to create artifacts, except for nearest.

image

Zooming in creates more artifacts:
image

Zooming in to one of these artifacts, reveals this:
image

Code for reproduction

import matplotlib.pyplot as plt
import matplotlib.colors

heatmap = [[0] * 32 for _ in range(128)]
cnt = 0
last = 1
for lvl in range(127):
    if lvl % 20 < 10:
        for i in range(32):
            heatmap[lvl][i] = 40
    else:
        for i in range(32):
            heatmap[lvl][i] = 0
jet = plt.get_cmap('jet')
jet.set_bad('white', 1)

plt.imshow(heatmap, origin='lower', interpolation='gaussian', aspect='auto', cmap=jet,
                 norm=matplotlib.colors.LogNorm())
plt.show()

Matplotlib version

  • Operating system: Windows
  • Matplotlib version: 2.1.0
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.6
  • Jupyter version (if applicable):
  • Other libraries:

Activity

  1. added this to the milestone on Dec 8, 2017
  2. tacaswell commented on Dec 8, 2017

    @tacaswell
    Member

    Interesting that you do not see the 'fuzz' on linux. This is due to some instability in the interpolation over big constant regions near the clipping limits.

    Duplicate of #8947

  3. jklymak commented on Dec 8, 2017

    @jklymak
    Member

    When you interpolate using "Gaussian" you are probably getting data that is "near" zero, but not quite due to floating point round off, which is different between machines. It doesn't show up as white because its not quite invalid...

    I'm not actually sure why imshow has an interpolation keyword as it seems to cause no end of trouble. Having the user do the interpolation themsleves outside of imshow would get rid of a black box that is expected to work magically.

  4. arthur00 commented on Dec 8, 2017

    @arthur00
    Author

    I've "solved" it by creating a custom colormap that defines 0 as white (which was my intention anyway), and by adding clip=True on the LogNorm. The artifacts are probably still there, but now at least they are the same color.

    I am not familiar with the codebase of matplotlib, but I believe @jklymak has a point in that using imshow with interpolation does not give the user any chance to customize interpolation results. Interpolating before would allow fixing rounding errors.

    @tacaswell The reason I do not see it in Linux is that the interpolation function does not work on the 'masked' area.

    image

  5. dstansby commented on Apr 5, 2018

    @dstansby
    Member

    Is this still a problem in version 2.2?

  6. arthur00 commented on Apr 9, 2018

    @arthur00
    Author

    I just checked against 2.2 and the artifacts are gone. There was another curious side-effect: the LogNorm would return 'bad' for value of 0, and now it seems to return a valid value, since my original code now prints an entirely blue squared plot with no white stripes. I reproduced the stripes by writing np.nan instead of 0, and verified artifacts are gone.

    If LogNorm for 0 should have returned np.nan (and thus created the white stripes), a bug should be filed for that. But as for this particular bug, it has been resolved. Thanks!

  7. tacaswell commented on Apr 12, 2018

    @tacaswell
    Member

    @arthur00 LogNorm returning valid values for 0 seems like a bug, can you open a new issue for that?

    The reason imshow needs an interpolation kwarg is that the number and pitch of the pixels in the input image and the number and pitch of the pixels in the output image do not match so there will be interpolation (either up or down sampling). There is not a generic 'right' way to do this, so we expose a way for the user to change it.

  8. arthur00 commented on Apr 12, 2018

    @arthur00
    Author

    LogNorm seems to be correctly returning 'masked' for 0, however the set_bad('white') does not seem to be working anymore. LogNorm(np.nan) returns 0.0 for some reason - I imagined it would return 'masked'.

    Running the snippet of code I wrote at the beginning will create a blue squared block on matplotlib 2.2.0 (Windows) and will create graph with horizontal stripes on matplotlib 2.1.1 (Windows)

  9. tacaswell commented on Apr 12, 2018

    @tacaswell
    Member

    what versions of numpy are you using in the two cases?

  10. tacaswell commented on Apr 12, 2018

    @tacaswell
    Member
    In [143]: n = LogNorm(vmin=1, vmax=5)
    
    In [144]: n(1)
    Out[144]: 0.0
    
    In [145]: n(.5)
    Out[145]: -0.43067655807339306
    
    In [146]: n(np.nan)
    Out[146]: nan
    
    In [147]: n(0)
    Out[147]: masked
    
    In [148]: type(n(0))
    Out[148]: numpy.ma.core.MaskedConstant
    
    In [149]: n([1, 2, 5, 12, 0, np.nan])
    /home/tcaswell/src/p/matplotlib/lib/matplotlib/colors.py:1031: RuntimeWarning: invalid value encountered in less_equal
      val = np.ma.asarray(value)
    Out[149]: 
    masked_array(data = [0.0 0.43067655807339306 1.0 1.5439593106327716 -- nan],
                 mask = [False False False False  True False],
           fill_value = 1e+20)
    
    In [150]: 
  11. arthur00 commented on Apr 12, 2018

    @arthur00
    Author

    I have opened another bug to explore this issue: #11039

  12. arthur00 commented on Apr 12, 2018

    @arthur00
    Author

    Ok, I tried rerunning my original code and setting vmin/vmax, and now it worked but the artifacts are back.

    image

    image

    I guess the artifacts dissapeared because np.nan was returning 0.0, not masked. The 'masked' values interpolation seem to be issue here.

    Reopening this issue as well, but feel free to close if this is not a relevant bug.

  13. timhoffm commented on Jul 16, 2020

    @timhoffm
    Member

    Cannot reproduce as of v3.3.0. Please reopen if the problem still persists.

  14. removed this from the future releases milestone on Oct 6, 2022
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

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions