WITC
WITC

Reputation: 329

How to plot data in QML Qt Charts (with python)

I want to plot data in Qt charts (QML) from python. The x,y data are saved in array x = np.array([0, 6]) y = np.array([0, 250]) . I am desperate how to pass these data to Qt Charts with one step. I can do it (step by step) with Signal/Slot, where the Signal is with parameters (x,y).

My working (very slow) code:

Creating signal from python to qml:

class AppWindow(QObject):

    # Signals from python to QML
    sigPlotData = Signal(int, int, arguments=['x','y'])

and later () I generate and send data to chart like that:

...      
for i in range(50):
   self.app.sigPlotData.emit(i, random.randint(0,150))
...

In QML file I do this:

 //connections from Python to QML via signals
    Connections {
        target: backend

        function onSigPlotData(x,y){
          
            lineSer.append(x, y);
        }
    }

ChartView {
 id: chartView
 title: "Line"
 anchors.fill: parent

ValueAxis{
     id: axisX
     min: 0
     max: maxX
     }

 ValueAxis{
    id: axisY
    min: 0
    max: 150
  }

 LineSeries {
 id: lineSer
 name: "data"
 axisX: axisX
 axisY: axisY
 }
}

Thank you very much for help.

Upvotes: 1

Views: 2467

Answers (2)

WITC
WITC

Reputation: 329

For me the best solution:

start = time.time()
points = []
for i in self.x:
     points.append(QPointF(i, self.y[i]))   # filling points with my prepared data 
serie1.replace(points)  # fill list of points in one call
end = time.time()
print(end - start)

for 50000 values it takes only 126 ms, for 5000 values it takes 13 ms

Upvotes: 0

Parisa.H.R
Parisa.H.R

Reputation: 3893

you can have this :

in main.py :

import os
from pathlib import Path
import sys

from PyQt5.QtCore import QCoreApplication, Qt, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine

CURRENT_DIRECTORY = Path(__file__).resolve().parent


def main():
    app = QApplication(sys.argv)

    engine = QQmlApplicationEngine()

    filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
    url = QUrl.fromLocalFile(filename)

    def handle_object_created(obj, obj_url):
        if obj is None and url == obj_url:
            QCoreApplication.exit(-1)

    engine.objectCreated.connect(
        handle_object_created, Qt.ConnectionType.QueuedConnection
    )
    engine.load(url)

    sys.exit(app.exec())


if __name__ == "__main__":
    main()

and in main.qml :

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtCharts 2.15

ApplicationWindow {
    visible: true
    width: 600
    height: 300
    property int timeStep: 0

    ChartView {
        id: chartView
        anchors.fill: parent

        ValueAxis {
            id: axisX
            min: 0
            max: 400
        }

        LineSeries {
            id: series1
            axisX: axisX
            name: "data"
        }

    }

    Timer {
        interval: 100
        repeat: true
        running: true
        onTriggered: {
            timeStep++;
            var y = (1+Math.cos(timeStep/10.0))/2.0;
            series1.append(timeStep, y);
        }
    }
}

Result is:

enter image description here

In QML you can create your function or other things like(for, if,..) with javascript syntax

and as you see I use series1.append(timeStep, y); means append function for adding data.

Upvotes: 2

Related Questions