pythonpyqt5qtchartsqchart

How to add data to the chart (QtChart)?


A task:

  1. Draw a graph in GUI(PyQT5) on the widget Frame(PyQt5) (this is important).
  2. The live-chart is updated 1 time per second. The X axis is the time axis.

What happened:

  1. Draw a chart (only axis and grid) on the widget

What didn't work:

  1. New points are not added to the chart
  2. The time axis, despite the setting, does not display the time.

Code:

from random import uniform
import sys
from PyQt5 import uic, QtChart, QtCore
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtChart import QChart, QChartView, QLineSeries

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('QtChart.ui', self)

        # Create chart
        chart = self.create_linechart()

        # Create PyQt widget for painting
        chart_widget = self.chart
        my_layout = QVBoxLayout(chart_widget)
        self.chart.setLayout(my_layout)
        my_layout.addWidget(chart)

        # Setting the axis to display dates
        self.axis_x = QtChart.QDateTimeAxis()
        self.axis_x.setTickCount(100)
        self.axis_x.setFormat("h:mm")
        self.axis_x.setTitleText("Date")

        # Timer for update data 1 time per second
        self.timer_update_events = QTimer()
        self.timer_update_events.timeout.connect(self.update_data)
        self.timer_update_events.start(1000)

        self.show()

    def update_data(self):
        time_now = QtCore.QDateTime.currentDateTime()
        y = uniform(0, 1)
        self.series.append(time_now.toMSecsSinceEpoch(), y)

    def create_linechart(self):
        self.series = QLineSeries()
        chart = QChart()
        chart.addSeries(self.series)
        chart.createDefaultAxes()
        chartview = QChartView(chart)
        return chartview

if __name__ == "__main__":
    App = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(App.exec_())

How to add new points and set the time on the X-axis?

The loaded QtChart.ui interface file (its code... create *.txt file and rename QtChart.ui):

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1007</width>
    <height>789</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QFrame" name="chart">
    <property name="geometry">
     <rect>
      <x>50</x>
      <y>30</y>
      <width>901</width>
      <height>681</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color: rgb(255, 255, 255);</string>
    </property>
    <property name="frameShape">
     <enum>QFrame::StyledPanel</enum>
    </property>
    <property name="frameShadow">
     <enum>QFrame::Raised</enum>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1007</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

Solution

  • Creating a QDateTimeAxis does not imply that it will be added to the chart and less attached to the series. On the other hand, the axes do not automatically calculate the visible range.

    class Window(QMainWindow):
        def __init__(self):
            super().__init__()
            uic.loadUi("QtChart.ui", self)
    
            # Create chart
            self.chartview = self.create_chart()
            self.series = self.create_linechart()
    
            self.chartview.chart().addSeries(self.series)
    
            # Setting the axis to display dates
            self.axis_x = QtChart.QDateTimeAxis()
            self.axis_x.setFormat("h:mm")
            self.axis_x.setTitleText("Date")
            self.chartview.chart().addAxis(self.axis_x, QtCore.Qt.AlignBottom)
            self.series.attachAxis(self.axis_x)
    
            self.axis_y = QtChart.QValueAxis()
            self.chartview.chart().addAxis(self.axis_y, QtCore.Qt.AlignLeft)
            self.series.attachAxis(self.axis_y)
    
            # Create PyQt widget for painting
            my_layout = QVBoxLayout(self.chart)
            my_layout.addWidget(self.chartview)
    
            # Timer for update data 1 time per second
            self.timer_update_events = QTimer()
            self.timer_update_events.timeout.connect(self.update_data)
            self.timer_update_events.start(1000)
    
            QTimer.singleShot(0, self.update_data)
    
        def update_data(self):
            time_now = QtCore.QDateTime.currentDateTime()
            if self.series.count() == 0:
                self.axis_x.setMin(time_now)
            y = uniform(0, 1)
            self.series.append(time_now.toMSecsSinceEpoch(), y)
            self.axis_x.setMax(time_now)
    
        def create_chart(self):
            chart = QChart()
            chartview = QChartView(chart)
            return chartview
    
        def create_linechart(self):
            series = QtChart.QLineSeries()
            return series