You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyQt对话框中同步显示控制台文本输出与生成的图表?

Solution to Display Console Outputs in PyQt Window

Hey there! I see you want to move those console-based result explanations into your PyQt dialog alongside the chart. Let's modify your code to add a text panel that captures and displays all those print statements, plus we'll fix a tiny bug in your counting logic along the way.

Step-by-Step Modifications:

  1. Add a Text Display Widget: We'll use QTextEdit to create a read-only panel for showing results clearly.
  2. Redirect Console Output: Build a custom stream handler to route print() calls directly to the QTextEdit widget.
  3. Fix Counting Bug: Your count4 condition was using modelSVM.predict(i) (which would throw an error) — we'll correct that to check if i ==4.
  4. Update Deprecated Code: Replace the old cross_validation module with the current model_selection from scikit-learn.

Modified Full Code:

import sys
import io
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout, QTextEdit
from numpy import genfromtxt
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC, SVC
from sklearn.decomposition import PCA
from itertools import cycle
from sklearn.model_selection import train_test_split, StratifiedKFold
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

# Custom stream to redirect print output to QTextEdit
class ConsoleStream(io.StringIO):
    def __init__(self, text_edit):
        super().__init__()
        self.text_edit = text_edit

    def write(self, text):
        super().write(text)
        # Append text to the widget and auto-scroll to bottom
        self.text_edit.append(text.strip())
        self.text_edit.verticalScrollBar().setValue(self.text_edit.verticalScrollBar().maximum())

    def flush(self):
        # Required for stream compatibility with print()
        pass

class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle("Heart Disease Prediction Results")
        self.resize(1000, 700)

        # Plot setup
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Action button
        self.button = QPushButton('Run Prediction & Plot')
        self.button.clicked.connect(self.my_model)

        # Results text panel
        self.result_text = QTextEdit()
        self.result_text.setReadOnly(True)
        self.result_text.setPlaceholderText("Prediction results will appear here...")

        # Redirect console output to the text panel
        self.console_stream = ConsoleStream(self.result_text)
        sys.stdout = self.console_stream

        # Layout arrangement
        layout = QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        layout.addWidget(self.result_text)
        self.setLayout(layout)

    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)
        ax.legend()
        self.canvas.draw()

    def my_model(self):
        # Clear previous content
        self.result_text.clear()
        ax = self.figure.add_subplot(111)
        ax.clear()

        # Load and prepare data
        dataset = genfromtxt('cleveland_data.csv', dtype=float, delimiter=',')
        X = dataset[:, 0:12]
        y = dataset[:, 13]

        # Apply PCA
        pca = PCA(n_components=5, whiten=True).fit(X)
        X_new = pca.transform(X)

        # Generate plot
        target_names = ['Class 0', 'Class 1', 'Class 2', 'Class 3', 'Class 4']
        self.plot_2D(X_new, y, target_names, ax)

        # Linear SVM Evaluation
        print("=== Linear SVM (Train-Test Split) ===")
        modelSVM = LinearSVC(C=0.001)
        X_train, X_test, y_train, y_test = train_test_split(X_new, y, test_size=0.4, train_size=0.6, random_state=0)
        modelSVM.fit(X_train, y_train)
        score = modelSVM.score(X_test, y_test)
        print(f"Test Accuracy: {score:.4f}")

        # Prediction class distribution
        print("\n=== Prediction Class Distribution ===")
        count0 = count1 = count2 = count3 = count4 = 0
        for pred in modelSVM.predict(X_new):
            if pred == 0:
                count0 +=1
            elif pred ==1:
                count1 +=1
            elif pred ==2:
                count2 +=1
            elif pred ==3:
                count3 +=1
            elif pred ==4:
                count4 +=1
        total = count0 + count1 + count2 + count3 + count4
        print(f"Class 0: {count0} ({count0/total:.2%})")
        print(f"Class 1: {count1} ({count1/total:.2%})")
        print(f"Class 2: {count2} ({count2/total:.2%})")
        print(f"Class 3: {count3} ({count3/total:.2%})")
        print(f"Class 4: {count4} ({count4/total:.2%})")

        # RBF SVM Evaluation
        print("\n=== RBF SVM (Train-Test Split) ===")
        modelSVM2 = SVC(C=0.001, kernel='rbf')
        X_train1, X_test1, y_train1, y_test1 = train_test_split(X_new, y, test_size=0.4, train_size=0.6, random_state=0)
        modelSVM2.fit(X_train1, y_train1)
        score2 = modelSVM2.score(X_test1, y_test1)
        print(f"Test Accuracy: {score2:.4f}")

        # Stratified K-Fold Cross Validation
        print("\n=== RBF SVM (Stratified 5-Fold Cross Validation) ===")
        skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
        fold_scores = []
        for fold_idx, (train_index, test_index) in enumerate(skf.split(X, y), 1):
            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.fit(X_train3, y_train3)
            fold_score = modelSVM3.score(X_test3, y_test3)
            fold_scores.append(fold_score)
            print(f"Fold {fold_idx} Accuracy: {fold_score:.4f}")
        print(f"\nMean Cross-Validation Accuracy: {np.mean(fold_scores):.4f}")

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

Key Changes Explained:

  • Console Redirection: The ConsoleStream class captures every print() output and appends it to the text panel, with auto-scrolling so you always see the latest results.
  • Improved Readability: Added section headers, percentage distributions, and rounded accuracy scores to make results easier to interpret.
  • Bug Fix: Corrected the count4 logic to avoid runtime errors.
  • Modernized Imports: Switched to the supported model_selection module instead of the deprecated cross_validation.

Now when you click the button, both the PCA plot and all model evaluation results will display in the same window—no more switching back to the console!

内容的提问来源于stack exchange,提问作者Kat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:47:32