I am working with the matplotlib
library and PyQt5
with Python 3.6
. I add a figure in a window I create, and I wish to set transparent the background of this figure because I add an image to the background of the window. But, the figure is not really transparent, it duplicates the background image of the window.
For example, someone deals with the same problem two years ago :
matplotlib and pyqt4 transparent background
Here is a working example (with a background which is black but the figure is not black) :
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_())
I search for answer during long hours but didn't find a solution yet. Thanks for any help you can bring !
The problem occurs because the background image is set as a palette to the widget. This causes the canvas to inherit the palette and hence the canvas will also have the image as background, somehow overlaying the widget's background.
A solution would be to set the background of the canvas transparent. An easy way to do so are style sheets.
self.canvas.setStyleSheet("background-color:transparent;")
Note that this is not the same as setting the patches' facecolor to none. The figure has a background, which is controlled inside matplotlib, but the canvas, being a PyQt object also has a background.
Complete example:
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_())
which might then look like
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With