PROGRAMMING : Redirect the console output of the code below via PyQT GUI and have the graph generated to be displayed in a PyQt window.
I saw this heart disease detecting program in GitHub, and I was wondering if I could display the generated graph to a GUI using PyQt. I tried displaying it on a PyQt window, and so far it does show up in the pop up window, but instead the graph appears at the python IDE's console. Here's the original code I was playing around with:
#This code performs the classification of heart disease by
labeling the predicted values
# in various classes, namely 0 for absence and 1 to 4 for presence
and also try
# to check the model performance by comparing it against other
Classifiers
from numpy import genfromtxt
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC
from sklearn.decomposition import PCA
import pylab as pl
from itertools import cycle
from sklearn import cross_validation
from sklearn.svm import SVC
#Loading and pruning the data
dataset = genfromtxt('cleveland_data.csv',dtype = float,
delimiter=',')
#print dataset
X = dataset[:,0:12] #Feature Set
y = dataset[:,13] #Label Set
#Method to plot the graph for reduced Dimesions
def plot_2D(data, target, target_names):
colors = cycle('rgbcmykw')
target_ids =
range(len(target_names))
plt.figure()
for i, c, label in zip(target_ids, colors,
target_names):
plt.scatter(data[target == i, 0], data[target == i, 1],
c=c, label=label)
plt.legend()
plt.savefig('Reduced_PCA_Graph')
# Classifying the data using a Linear SVM and predicting the
probability of disease belonging to a particular class
modelSVM = LinearSVC(C=0.001)
pca = PCA(n_components=5, whiten=True).fit(X)
X_new = pca.transform(X)
# calling plot_2D
target_names = ['0','1','2','3','4']
plot_2D(X_new, y, target_names)
#Applying cross validation on the training and test set for
validating our Linear SVM Model
X_train, X_test, y_train, y_test =
cross_validation.train_test_split(X_new, y, test_size=0.4,
train_size=0.6, random_state=0)
modelSVM = modelSVM.fit(X_train, y_train)
print("Testing Linear SVC values using Split")
print(modelSVM.score(X_test, y_test))
# printing the Likelihood of disease belonging to a particular
class
# predicting the outcome
count0 = 0
count1 = 0
count2 = 0
count3 = 0
count4 = 0
for i in modelSVM.predict(X_new):
if i == 0:
count0 = count0+1;
elif i == 1:
count1 = count1+1;
elif i == 2:
count2 = count2+1;
elif i == 3:
count3 = count3+1;
elif modelSVM.predict(i)
==4:
count4 = count4+1
total = count0+count1+count2+count3+count4
#Predicting the Likelihood
#Applying the Principal Component Analysis on the data
features
modelSVM2 = SVC(C=0.001,kernel='rbf')
#Applying cross validation on the training and test set for
validating our Linear SVM Model
X_train1, X_test1, y_train1, y_test1 =
cross_validation.train_test_split(X_new, y, test_size=0.4,
train_size=0.6, random_state=0)
modelSVM2 = modelSVM2.fit(X_train1, y_train1)
print("Testing with RBF using split")
print(modelSVM2.score(X_test1, y_test1))
#Using Stratified K Fold
skf = cross_validation.StratifiedKFold(y, n_folds=5)
for train_index, test_index in skf:
# print("TRAIN:", train_index, "TEST:",
test_index)
X_train3, X_test3 = X[train_index],
X[test_index]
y_train3, y_test3 = y[train_index],
y[test_index]
modelSVM3 = SVC(C=0.001,kernel='rbf')
modelSVM3 = modelSVM3.fit(X_train3, y_train3)
print("Testing using stratified with K folds")
print(modelSVM3.score(X_test3, y_test3))
If this program was executed, it will generate a scatter graph on the project's console. Now what I want to happen is, the scatter graph should be in a PyQt window. What's the best way around to do that?
The best way was to use
matplotlib.backends.backend_qt4agg to display
matplotlib plot in pyQt.I have just made a small pyQT program
having a canvas widget where the graph will be displayed and a
button to run the code.(press the button and you will see graph in
few seconds) I put the code u gave in a method called
my_model. I changed plot_2D function a bit because
now we want to plot on the canvas.I have commented the code so that
you can understand it.The print values will be displayed on the
terminal.I used pyQt4.
Code:
import sys
from PyQt4 import QtGui
from numpy import genfromtxt
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC
from sklearn.decomposition import PCA
import pylab as pl
from itertools import cycle
from sklearn import cross_validation
from sklearn.svm import SVC
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT
as NavigationToolbar
from matplotlib.figure import Figure
import random
class Window(QtGui.QDialog):
def __init__(self, parent=None):
super(Window,
self).__init__(parent)
# a figure instance
to plot on
self.figure =
Figure()
# this is the Canvas
Widget that displays the `figure`
# it takes the `figure`
instance as a parameter to __init__
self.canvas =
FigureCanvas(self.figure)
# this is the
Navigation widget
# it takes the Canvas
widget and a parent
self.toolbar =
NavigationToolbar(self.canvas, self)
# Just some button
connected to `my_model` method
self.button =
QtGui.QPushButton('Run my Code')
self.button.clicked.connect(self.my_model)
# set the
layout
layout =
QtGui.QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
#Method to plot the graph for reduced
Dimesions
def plot_2D(self,data, target,
target_names,ax):
colors =
cycle('rgbcmykw')
target_ids =
range(len(target_names))
for i, c, label in
zip(target_ids, colors, target_names):
ax.scatter(data[target == i, 0], data[target == i, 1],
c=c, label=label)
def my_model(self):
''' plot some random
stuff '''
#Loading and pruning the
data
dataset =
genfromtxt('cleveland_data.csv',dtype = float, delimiter=',')
#print dataset
X = dataset[:,0:12]
#Feature Set
y =
dataset[:,13] #Label Set
# Classifying the
data using a Linear SVM and predicting the probability of disease
belonging to a particular class
modelSVM =
LinearSVC(C=0.001)
pca =
PCA(n_components=5, whiten=True).fit(X)
X_new =
pca.transform(X)
# calling
plot_2D
target_names =
['0','1','2','3','4']
# create an
axis
ax =
self.figure.add_subplot(111)
# discards the old
graph
ax.clear()
self.plot_2D(X_new, y,
target_names,ax)
# refresh canvas
self.canvas.draw()
#Applying cross
validation on the training and test set for validating our Linear
SVM Model
X_train, X_test,
y_train, y_test = cross_validation.train_test_split(X_new, y,
test_size=0.4, train_size=0.6, random_state=0)
modelSVM =
modelSVM.fit(X_train, y_train)
print("Testing Linear
SVC values using Split")
print(modelSVM.score(X_test, y_test))
# printing the
Likelihood of disease belonging to a particular class
# predicting the
outcome
count0 = 0
count1 = 0
count2 = 0
count3 = 0
count4 = 0
for i in
modelSVM.predict(X_new):
if i == 0:
count0 = count0+1;
elif i == 1:
count1 = count1+1;
elif i == 2:
count2 = count2+1;
elif i == 3:
count3 = count3+1;
elif modelSVM.predict(i) ==4:
count4 = count4+1
total =
count0+count1+count2+count3+count4
#Predicting the
Likelihood
#Applying the
Principal Component Analysis on the data features
modelSVM2 =
SVC(C=0.001,kernel='rbf')
#Applying cross
validation on the training and test set for validating our Linear
SVM Model
X_train1, X_test1,
y_train1, y_test1 = cross_validation.train_test_split(X_new, y,
test_size=0.4, train_size=0.6, random_state=0)
modelSVM2 =
modelSVM2.fit(X_train1, y_train1)
print("Testing with RBF
using split")
print(modelSVM2.score(X_test1, y_test1))
#Using Stratified K
Fold
skf =
cross_validation.StratifiedKFold(y, n_folds=5)
for train_index,
test_index in skf:
#
print("TRAIN:", train_index, "TEST:", test_index)
X_train3, X_test3 = X[train_index], X[test_index]
y_train3, y_test3 = y[train_index], y[test_index]
modelSVM3 =
SVC(C=0.001,kernel='rbf')
modelSVM3 =
modelSVM3.fit(X_train3, y_train3)
print("Testing using
stratified with K folds")
print(modelSVM3.score(X_test3, y_test3))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
-----------------------------------------------------
PS: I referred this https://stackoverflow.com/questions/12459811/how-to-embed-matplotlib-in-pyqt-for-dummies for coming up with the solution.
Hope you understood how to display a plot in PyQt window.
PROGRAMMING : Redirect the console output of the code below via PyQT GUI and have the...