python – AttributeError: module ‘pandas.plotting._matplotlib’ has no attribute ‘plot’

I am at a complete loss as to what is causing this problem, so hopefully someone here can help. Basically, I have built a GUI application using PyQt5 that works perfectly when ran as a .py file, no errors at all, but when I converted it to an .exe file using cx_freeze, my plotting function breaks, returning the error:

Traceback (most recent call last):
  File "main2.py", line 266, in randomForest
  File "C:UserstylerAppDataLocalProgramsPythonPython39libsite-packagespandasplotting_core.py", line 972, in __call__
    return plot_backend.plot(data, kind=kind, **kwargs)
AttributeError: module 'pandas.plotting._matplotlib' has no attribute 'plot'

Again, this function works in a .py file, but not in the .exe. Below is the relevant code that it’s trying to run.

# Importing modules / libraries
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as Navi
from matplotlib.figure import Figure
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn import svm
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
import sip
from sklearn.ensemble import IsolationForest
from sklearn.svm import OneClassSVM

# Canvas class to display the graph
class MatplotlibCanvas(FigureCanvasQTAgg):
    # Setting graph dimensions
    def __init__(self,parent=None, dpi = 120):
        # Creating figure
        fig = Figure(dpi = dpi)

        # Create axes and add them to the figure as subplots
        self.axes = fig.add_subplot(111)
        
        super(MatplotlibCanvas,self).__init__(fig)
        
        # Setting figure layout
        fig.tight_layout()

# UI class
class Ui_MainWindow(object):
    # Create UI
    def setupUi(self, MainWindow):
        # Create MainWindow
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(947, 633)

        # Create centralwidget
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # Layout centralwidget in a grid
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        # Create horizontal layout to hold the buttons
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")

        # Button to activate the random forest classifier, and it to the horizontal layout
        self.randomForestButton = QtWidgets.QPushButton(self.centralwidget)
        self.randomForestButton.setObjectName("randomForestButton")
        self.horizontalLayout.addWidget(self.randomForestButton)

        # Button to activate the SVM classifier, and it to the horizontal layout
        self.svmButton = QtWidgets.QPushButton(self.centralwidget)
        self.svmButton.setObjectName("svmButton")
        self.horizontalLayout.addWidget(self.svmButton)

        # Button to activate the isolation forest algorithm, and it to the horizontal layout
        self.isolationForestButton = QtWidgets.QPushButton(self.centralwidget)
        self.isolationForestButton.setObjectName("isolationForestButton")
        self.horizontalLayout.addWidget(self.isolationForestButton)

        # Button to activate the One-Class SVM algorithm, and it to the horizontal layout
        self.oneclassSVMButton = QtWidgets.QPushButton(self.centralwidget)
        self.oneclassSVMButton.setObjectName("oneclassSVMButton")
        self.horizontalLayout.addWidget(self.oneclassSVMButton)

        # Create horizontal spacer
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)

        # Specifying dimensions of the horizontal layout
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)

        # Create second horizontal layout for the labels
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setObjectName("comboBox")
        for i in range(101):
            self.comboBox.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox)
        
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        
        self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_2.setObjectName("comboBox_2")
        for i in range(101):
            self.comboBox_2.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox_2)
        
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_2.addWidget(self.label_3)
        
        self.comboBox_3 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_3.setObjectName("comboBox_3")
        for i in range(101):
            self.comboBox_3.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox_3)
        
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_2.addWidget(self.label_4)
        
        self.comboBox_4 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_4.setObjectName("comboBox_4")
        for i in range(101):
            self.comboBox_4.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox_4)
        
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_2.addWidget(self.label_5)
        
        self.comboBox_5 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_5.setObjectName("comboBox_5")
        for i in range(5):
            self.comboBox_5.addItem("")
        self.horizontalLayout_2.addWidget(self.comboBox_5)
        
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        
        self.gridLayout.addLayout(self.horizontalLayout_2, 1, 0, 1, 1)
        
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        
        self.spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(self.spacerItem2)
        
        self.gridLayout.addLayout(self.verticalLayout, 2, 0, 1, 1)
        
        MainWindow.setCentralWidget(self.centralwidget)
        
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 947, 26))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        MainWindow.setMenuBar(self.menubar)
        
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        
        self.actionOpen_CSV_File = QtWidgets.QAction(MainWindow)
        self.actionOpen_CSV_File.setObjectName("actionOpen_CSV_File")
        
        self.actionExit = QtWidgets.QAction(MainWindow)
        self.actionExit.setObjectName("actionExit")
        
        self.menuFile.addAction(self.actionOpen_CSV_File)
        self.menuFile.addAction(self.actionExit)
        self.menubar.addAction(self.menuFile.menuAction())

        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.randomForestButton.setText(_translate("MainWindow", "Random Forest"))
        self.svmButton.setText(_translate("MainWindow", "SVM"))
        self.isolationForestButton.setText(_translate("MainWindow", "Isolation Forest"))
        self.oneclassSVMButton.setText(_translate("MainWindow", "One-Class SVM"))
        self.label.setText(_translate("MainWindow", "test_size"))
        self.label_2.setText(_translate("MainWindow", "random_state (train/test split)"))
        self.label_3.setText(_translate("MainWindow", "n_estimators"))
        self.label_4.setText(_translate("MainWindow", "random_state (classifier)"))
        self.label_5.setText(_translate("MainWindow", "kernel"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionOpen_CSV_File.setText(_translate("MainWindow", "Open CSV File"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))

        self.iterator1 = 0
        self.iterator2 = 0
        self.num1 = 0.0
        self.num2 = 0
        for i in range(101):
            self.comboBox.setItemText(self.iterator1, _translate("MainWindow", str(round(self.num1, 2))))
            self.iterator1 += 1
            self.num1 += 0.01
        for i in range(101):
            self.comboBox_2.setItemText(self.iterator2, _translate("MainWindow", str(round(self.num2, 2))))
            self.comboBox_3.setItemText(self.iterator2, _translate("MainWindow", str(round(self.num2, 2))))
            self.comboBox_4.setItemText(self.iterator2, _translate("MainWindow", str(round(self.num2, 2))))
            self.iterator2 += 1
            self.num2 += 1

        self.comboBox_5.setItemText(0, _translate("MainWindow", "linear"))
        self.comboBox_5.setItemText(1, _translate("MainWindow", "poly"))
        self.comboBox_5.setItemText(2, _translate("MainWindow", "rbf"))
        self.comboBox_5.setItemText(3, _translate("MainWindow", "sigmoid"))
        self.comboBox_5.setItemText(4, _translate("MainWindow", "precomputed"))
        
        self.filename=""
        self.canv = MatplotlibCanvas(self)

        self.actionOpen_CSV_File.triggered.connect(self.getFile)
        self.randomForestButton.clicked.connect(self.randomForest)
        self.svmButton.clicked.connect(self.SVM)
        self.isolationForestButton.clicked.connect(self.isolationForest)
        self.oneclassSVMButton.clicked.connect(self.oneclassSVM)
        
    def getFile(self):
        self.filename = QFileDialog.getOpenFileName(filter = "csv (*.csv)")[0]
        self.df = pd.read_csv(self.filename,encoding = 'utf-8').fillna(0)

    def randomForest(self):
        # Random forest classifier for the machine temperature system failure data
        y = self.df['Fault'].values
        X = self.df.drop(['Fault'], axis = 1)

        # Establishing training and testing sets.
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = float(self.comboBox.currentText()), random_state = int(self.comboBox_2.currentText()))

        # Defining the random forest classifier and fitting the model to the data
        model = RandomForestClassifier(n_estimators = int(self.comboBox_3.currentText()), random_state = int(self.comboBox_4.currentText()))
        model.fit(X_train, y_train)

        # Predicting the classes
        prediction_test = model.predict(X_test)

        accuracy = metrics.accuracy_score(y_test, prediction_test)
        
        percentage = "{:.2%}".format(accuracy)
            
        # Displaying prediction accuracy
        print("Accuracy = ", percentage)

        self.toolbar = Navi(self.canv,self.centralwidget)

        try:
            self.horizontalLayout.removeWidget(self.toolbar)
            self.verticalLayout.removeWidget(self.canv)

            sip.delete(self.toolbar)
            sip.delete(self.canv)
            self.toolbar = None
            self.canv = None
            self.verticalLayout.removeItem(self.spacerItem2)
        except Exception as e:
            print(e)
            pass

        self.canv = MatplotlibCanvas(self)

        self.verticalLayout.addWidget(self.canv)

        self.canv.axes.cla()
        self.ax = self.canv.axes
            
        if self.filename.find("temperature.csv") != -1:
            self.df = pd.read_csv("machine_temperature_system_failure.csv")

            self.df.plot(ax = self.canv.axes)

            self.ax.set_xlabel('timestamp')
            self.ax.set_ylabel('values')
            self.ax.set_title(str(percentage))
            self.ax.get_legend().remove()

            self.canv.draw()
        else:
            self.df.plot(ax = self.canv.axes)

            self.ax.set_xlabel('timestamp')
            self.ax.set_ylabel('values')
            self.ax.set_title(str(percentage))
            self.ax.get_legend().remove()

            self.canv.draw()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

A few things I’ve tried, based on similar questions I’ve seen here:

importing matplotlib.pyplot as plt

Uninstalling, updating, and reinstalling pandas.

Uninstalling and reinstalling matplotlib

I have generated the .exe using pyinstaller, cx_freeze, and py2exe and the error has occurred in all of them. cx_freeze is the one I would prefer to use.

Any ideas would be much appreciated.

Leave a Comment