Skip to content

qt5agg image quality changes when window is out of focus #13012

Closed

Description

@dcherian

Bug report

Bug summary

Quality of qt rendered figures is drastically reduced when window is moved out of focus and then back in focus.

Code for reproduction

import matplotlib.pypot as plt
plt.plot([1, 2, 3, 4], [5, 5.5, 6.5, 8.5], alpha=0.5)

Actual outcome

mpl-before

Switch to different window and back:
mpl-after

At this stage, calling plt.draw() fixes it till the window goes out of focus. Zooming in on the figure also returns it to the earlier quality. Note that transparency is lost.

Expected outcome

Rendering doesn't change.

Matplotlib version

  • Operating system: Ubuntu 16.04
  • Matplotlib version: 3.0.2
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.6.7
  • Jupyter version (if applicable): console 6.0.0
  • Other libraries: pyqt 5.6.0 py36h8210e8a_7 conda-forge

everything installed from conda-forge using conda.

Activity

  1. WeatherGod commented on Dec 17, 2018

    @WeatherGod
    Member
  2. dcherian commented on Dec 17, 2018

    @dcherian
    Author

    I'm using Xfce and the Tk backend works fine.

  3. tacaswell commented on Dec 18, 2018

    @tacaswell
    Member

    Note that transparency is lost.

    Do you have other transparency than the alpha on the line?

  4. dcherian commented on Dec 18, 2018

    @dcherian
    Author

    No, but axes.facecolor=None and figure.facecolor=None. Does that count?

  5. tacaswell commented on Dec 18, 2018

    @tacaswell
    Member

    Yes, that is likely the critical detail! If you repeatedly focus / defocus does it get worse?

    I think what is going on is that for GUI backends we use Agg to render and RGBA buffer and then use the GUI frameworks drawImage or equivalent to paint the figure onto your screen (see https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_qt5agg.py#L23) for details. If you set the Figure and Axes color to None the alpha on most of the rendered figure is 0. Unfortunately, we only clear the Qt painter right after triggering a draw (

    if self._erase_before_paint:
    painter.eraseRect(self.rect())
    self._erase_before_paint = False
    ). On a repaint where we did re-draw we just re-use the same buffer and draw to the screen. If you have an opaque background, this is OK as when Qt does the compositing the opaque layer is the only thing that survives, however all of your pixels have non-zero alpha so we are repeatedly compositing it with its self.

    If you delete the 3 lines above does the problem go away?

  6. added this to the v3.1 milestone on Dec 18, 2018
  7. dcherian commented on Dec 18, 2018

    @dcherian
    Author

    If you repeatedly focus / defocus does it get worse?

    Yes!

    When I remove those three lines my figure background is black.

  8. tacaswell commented on Dec 18, 2018

    @tacaswell
    Member

    How about leaving just painter.eraseRect(self.rect()) ?

  9. dcherian commented on Dec 19, 2018

    @dcherian
    Author

    Yup, commenting out this line fixes things:

    self._erase_before_paint = False

  10. added 2 commits that reference this issue on Dec 25, 2018
    79ed0ee
    f4948aa
  11. added a commit that references this issue on Dec 30, 2018
    879b7f0
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

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions