Matplotlib和透明度图像

6
我正在使用Python 3.6中的matplotlib库和PyQt5。我在创建的窗口中添加了一个图形,希望为该图形设置透明背景,因为我将图像添加到窗口的背景中。但是,该图形并不真正透明,它会重复窗口的背景图像。
例如,有人两年前遇到了同样的问题: matplotlib and pyqt4 transparent background 这里有一个可工作的示例(具有黑色背景,但图形不是黑色的):
import sys, os
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import matplotlib
matplotlib.use('Qt5Agg') # Make sure that we are using QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

class SecondWindow(QWidget):
    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent)
        self.setupUi(self)

    def setupUi(self, Form):
        # WINDOW SETTINGS
        Form.setWindowTitle('Hello')
        self.p = QPalette()
        self.pixmap = QPixmap(os.getcwd() + "/logo.png").scaled(self.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
        self.p.setBrush(QPalette.Background, QBrush(self.pixmap))
        self.setPalette(self.p)

        # CREATE FIGURE AND SETTINGS
        self.figure = plt.figure()
        self.figure.patch.set_facecolor('None')
        self.figure.patch.set_alpha(0)
        self.canvas = FigureCanvas(self.figure)
        self.axes = self.figure.add_subplot(111)

        # WINDOW LAYOUT (with H1 and H2)
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.canvas,1)
        self.layout().setContentsMargins(50, 50, 50, 50)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = SecondWindow()
    form.show()
    sys.exit(app.exec_())

我花费了很长时间寻找答案,但还没有找到解决方案。谢谢你能提供的任何帮助!

  • 操作系统: Windows 7 Pro
  • Matplotlib版本: 2.0.2(通过Anaconda安装,使用命令conda install matplotlib --channel conda-forge)
  • Python版本: Python 3.6
  • Anaconda 3

我认为提供一个问题的 [mcve] 会很有帮助,这样那些想要在问题上进行实验的人可以轻松地开始。 - ImportanceOfBeingErnest
抱歉,今早我没时间完成它。 - Mathieu Gauquelin
这个例子既不能运行,也不够简洁。由于这个问题已经被提出并且未得到解答两年了,唯一能让你的问题不会成为荒野之风的方法就是提供一个问题的最小化、完整、可复现的代码示例(MCVE)。也就是说,忘记你的代码吧,写一个新的可以运行的代码(可以从问题中复制和粘贴),并展示问题。 - ImportanceOfBeingErnest
现在可以了 ;) 不过我不知道如何在他的电脑上找到一个经典的图片。 - Mathieu Gauquelin
1个回答

11

问题是由于将背景图像设置为小部件的调色板而引起的。这会导致画布继承了调色板,因此画布也将具有图像作为背景,从而覆盖了小部件的背景。

解决方法是将画布的背景设置为透明。一种简单的方法是使用样式表。

self.canvas.setStyleSheet("background-color:transparent;")

注意,这与将修补程序的facecolor设置为无色不同。图形有一个背景,由matplotlib内部控制,但画布作为PyQt对象也具有背景。

完整示例:

import sys, os
from PyQt4.QtCore import Qt
from PyQt4.QtGui import *

import matplotlib
matplotlib.use('Qt4Agg') 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
plt.rcParams['xtick.color'] ="w"
plt.rcParams['ytick.color'] ="w"
plt.rcParams['font.size'] = 14


class SecondWindow(QWidget):
    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent)

        # CREATE FIGURE AND SETTINGS
        self.figure = plt.figure()
        self.figure.patch.set_facecolor("None")
        self.canvas = FigureCanvas(self.figure)
        self.axes = self.figure.add_subplot(111)
        self.axes.patch.set_alpha(0.5)

        ###### Make the background of the canvas transparent
        self.canvas.setStyleSheet("background-color:transparent;")

        self.p = QPalette()
        self.p.setBrush(QPalette.Background, QBrush(QPixmap("house.png")))
        self.setPalette(self.p)

        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.canvas,1)
        self.layout().setContentsMargins(50, 50, 50, 50)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = SecondWindow()
    form.show()
    sys.exit(app.exec_())

那么它可能看起来像这样:

在此输入图片描述


谢谢,它有效!我一直在探索Qt和matplotlib,所以我没有想到尝试那个。 - Mathieu Gauquelin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接