Skip to content

[Bug]: DPI keeps doubling when creating a new MatPlotLib QtWidget in qt6 #26380

Closed

Description

@hydroEng

Bug summary

I ran into this bizarre bug, I am not sure if it's a skill issue on my end, but I am trying to embed a plot in my qt6 application. Allowing the user to plot and replot for some reason keeps increasing the sizes of my chart elements, but only when I have display scaling on (e.g. 125%, 150% etc). To illustrate:

wat

See below for the code, basically I am creating a new plot every time there is a mouse click on that row. Embedding print(self.chart.figure.dpi) shows that my plot's dpi keeps doubling every other time I trigger a click. Console output:

100.0
100.0
200.0
200.0
400.0
400.0

I can workaround this by explicitly setting the figure DPI, e.g. figure.dpi = 100 when creating it. But I assume that means I'm giving up display scaling

Code for reproduction

import matplotlib

matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
from PyQt6.QtWidgets import (
    QWidget,
    QVBoxLayout, QFrame
)

class GraphView(QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QVBoxLayout()
        self.separator = None
        self.chart = MplCanvas()

        self.figures = None

        self.init_widget()

    def init_widget(self):
        self.init_separator()
        self.layout.addWidget(self.separator)
        self.layout.addWidget(self.chart)
        self.setLayout(self.layout)
    ...
    # Note this is the code that triggers when I click a row.
    def update_graph(self, figure):

        self.chart.deleteLater()
        self.chart = MplCanvas(fig=figure)
    
        self.layout.addWidget(self.chart)
        self.layout.update()

class MplCanvas(FigureCanvasQTAgg):
    def __init__(self, fig=Figure()):
        super(MplCanvas, self).__init__(fig)

Actual outcome

Figure DPI keeps dynamically doubling

Expected outcome

DPI shouldn't double like that, it's madness ☹️

Additional information

No response

Operating system

Windows, Linux

Matplotlib Version

3.6.3

Matplotlib Backend

QtAgg

Python version

3.11.4

Jupyter version

No response

Installation

pip

Activity

  1. tacaswell commented on Jul 24, 2023

    @tacaswell
    Member

    Can you please try with a newer version of Matplotlib? I believe we have fixed this bug already.

  2. hydroEng commented on Jul 24, 2023

    @hydroEng
    Author

    Thanks @tacaswell, the issue is still present in ver 3.7.2.

    image

    If i get time I will write up some simple reproducible code.

  3. tacaswell commented on Jul 24, 2023

    @tacaswell
    Member

    Are you setting the DPI internally to your code?

    Are you updating one Figure or do you have more than one Figure that you show/hide? Do you do that show/hide by having more than one Canvas and then doing Qt things or do you have one canvas that you attach to each figure in turn?

  4. hydroEng commented on Jul 24, 2023

    @hydroEng
    Author

    (1) No, I am not setting DPI internally.
    (2) More than one figure, clicking the QTableWidget row effectively just requests a new figure. Every time a request is made a new MplCanvas object (inherits FigureCanvasQTAgg, see above) is being created and added to the Qt window as a widget. So basically the canvas is being deleted + new one being created every time a figure is requested.

  5. tacaswell commented on Jul 24, 2023

    @tacaswell
    Member

    If you are creating new Figure and FigureCanvasQtAgg each time, where is the scaled-up DPI being persisted? The source of the scaling is that on high DPI screens we upscale the user set DPI by what ever the pixel ratio is. IF you then read that DPI and set it back you can get these "always gets bigger" loops.

  6. hydroEng commented on Jul 24, 2023

    @hydroEng
    Author

    honestly, I don't know, since I don't set dpi settings anywhere in my code. I'll try write something reproducible for you.

  7. QuLogic commented on Jul 25, 2023

    @QuLogic
    Member

    the issue is still present in ver 7.4.2.

    There is no such version of Matplotlib?

  8. hydroEng commented on Jul 25, 2023

    @hydroEng
    Author

    the issue is still present in ver 7.4.2.

    There is no such version of Matplotlib?

    Sorry, I meant version 3.7.2 **

  9. hydroEng commented on Jul 25, 2023

    @hydroEng
    Author

    @tacaswell I can reproduce this bug with the following code (using v. 3.7.2). It seems like this occurs when plotting preexisting figures on a canvas (if creating a new figure each time "plot" is clicked, there are no issues). So I guess the dpi info is persisting in the figure object?

    Recording:

    bug

    Code:

    import sys
    import matplotlib
    import random
    
    matplotlib.use('Qt5Agg')
    from matplotlib.figure import Figure
    import matplotlib.pyplot as plt
    from PyQt6.QtWidgets import QWidget, QVBoxLayout, QApplication, QPushButton
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
    
    
    class App(QWidget):
    
        def __init__(self):
            super().__init__()
            self.layout = QVBoxLayout()
            self.chart = Canvas()
    
            self.btn = QPushButton("Plot")
            self.figs = self.make_figs()
            self.btn.clicked.connect(self.show_plots)
    
            self.layout.addWidget(self.btn)
            self.layout.addWidget(self.chart)
            self.setLayout(self.layout)
    
        def show_plots(self):
            i = random.choice([0, 1])
            figure = self.figs[i]
            self.chart.deleteLater()
            self.chart = Canvas(fig=figure)
    
            self.layout.addWidget(self.chart)
            self.layout.update()
    
        def make_figs(self):
            # test figures:
            fig1, ax1 = plt.subplots()
            fig2, ax2 = plt.subplots()
    
            data1 = [5, 10, 15, 20]
            data2 = [[20, 30, 18, 12], [3, 5, 7, 8]]
    
            ax1.boxplot(data1)
            ax2.scatter(data2[0], data2[1])
    
            return [fig1, fig2]
    
    
    class Canvas(FigureCanvasQTAgg):
        def __init__(self, fig=Figure()):
            super(Canvas, self).__init__(fig)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        ex = App()
        ex.show()
        sys.exit(app.exec())
  10. tom-a-horrocks commented on Nov 10, 2025

    @tom-a-horrocks

    I am also experiencing this bug, Matplotlib 3.10.7 and PySide 6.10.0. It happens each time I attach a new canvas to an existing Figure.

  11. timhoffm commented on Nov 10, 2025

    @timhoffm
    Member

    Possibly fixed through #29855 (comment).

  12. tacaswell commented on Nov 13, 2025

    @tacaswell
    Member

    Not fixed by #29855 but there is a simple fix, PR coming.

  13. added 2 commits that reference this issue on Nov 13, 2025
    7b06d8f
    c0041fb
  14. added this to the v3.11.0 milestone on Dec 11, 2025
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

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions