Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib and transparency figure

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 !

  • Operating System: Windows 7 Pro
  • Matplotlib Version: 2.0.2 (installed via Anaconda, conda install matplotlib --channel conda-forge)
  • Python Version: Python 3.6
  • Anaconda 3
like image 704
Mathieu Gauquelin Avatar asked Aug 11 '17 09:08

Mathieu Gauquelin


1 Answers

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

enter image description here

like image 189
ImportanceOfBeingErnest Avatar answered Nov 15 '22 12:11

ImportanceOfBeingErnest