2

I am trying to create plots with a Python GUI and gnuplot. I am generating the code in Python and send it to gnuplot. This basically works with piping data to gnuplot, but:

Disadvantages:

  1. the Python program is blocked until you close gnuplot
  2. you have to load/start gnuplot again and again everytime you're making a plot which seems to take annoying extra time (on slow computers)

My questions:

  1. how to keep the Python program responsive?
  2. is there a way to start gnuplot once and keep it running?
  3. how to just update the gnuplot terminal if there is a new plot?

Thank you for hints and links.

Here is my code:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit, QPushButton
import subprocess

class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setGeometry(100,100,400,200)
        self.myTextEdit = QPlainTextEdit()
        self.myTextEdit.setPlainText("plot sin(x)")
        self.button = QPushButton('Plot code',self)
        self.button.clicked.connect(self.on_button_click)
        vbox = QVBoxLayout(self)
        vbox.addWidget(self.myTextEdit)
        vbox.addWidget(self.button)
        self.setLayout(vbox)
    @pyqtSlot()

    def on_button_click(self):
        gnuplot_str = self.myTextEdit.document().toPlainText() + "\n"
        gnuplot_path = r'C:\Programs\gnuplot\bin\gnuplot.exe'
        plot = subprocess.Popen([gnuplot_path,'-p'],stdin=subprocess.PIPE)
        plot.communicate(gnuplot_str.encode())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())
theozh
  • 22,244
  • 5
  • 28
  • 72

1 Answers1

2

Instead of using subprocess you must use QProcess which is friendly to the Qt event loop as I show below:

import sys
from PyQt5.QtCore import QProcess, pyqtSlot
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit, QPushButton


class MyWindow(QWidget):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setGeometry(100,100,400,200)
        self.myTextEdit = QPlainTextEdit()
        self.myTextEdit.setPlainText("plot sin(x)")
        self.button = QPushButton('Plot code',self)
        self.button.clicked.connect(self.on_button_click)
        vbox = QVBoxLayout(self)
        vbox.addWidget(self.myTextEdit)
        vbox.addWidget(self.button)
        gnuplot_path = r'C:\Programs\gnuplot\bin\gnuplot.exe'
        self.process = QProcess(self)
        self.process.start(gnuplot_path, ["-p"])

    @pyqtSlot()
    def on_button_click(self):
        gnuplot_str = self.myTextEdit.document().toPlainText() + "\n"
        self.process.write(gnuplot_str.encode())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241