Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

qgraphicstextitem over QChartview



  • Hello, I'm trying to add some labels to a qchart to go along with the qscatterseries in order to add labels to the points. I set the labels position in "label.setPos(g[pos], s[pos])" and then try to get the scene from qchartsview and add the label. for some reason all the labels end up at the top left corner. I've done a bit of googling and can't get it to work. Thanks in advance for any help!

    0_1564676192225_a35c5e09-fdc0-438b-af7d-6020f60a60c6-image.png

    import sys
    from PySide2.QtUiTools import QUiLoader
    from PySide2.QtWidgets import QApplication, QAction, QFileDialog, QLabel, QLineEdit, \
        QMainWindow, QVBoxLayout, QWidget, QHBoxLayout, QInputDialog, QGraphicsTextItem
    from PySide2.QtCore import QFile, QObject
    from PySide2.QtCharts import QtCharts
    from PySide2.QtGui import QPixmap, QImage, QIntValidator, QDoubleValidator, QPainter
    import numpy as np
    
    class Chart(QMainWindow):
        def __init__(self):
            super().__init__()
    
            # chart creation hierarchy:
            # chartview-->charts-->series-->set(or points)
    
            # create chart widget
            self.chart = QtCharts.QChart()
            self.chart.legend().setVisible(False)
            self.chart.setTitle("Phasor Plot")
            self.setGeometry(0,0,800,500)
    
            # create chartview
            self.chartView = QtCharts.QChartView(self.chart)
            self.chartView.setRenderHint(QPainter.Antialiasing)
    
            g = [0.94058736, 0.79830002, 0.49735222, 0.3054408,  0.19831079, 0.1366765,
             0.09905082, 0.074736,   0.0582399,  0.04658614, 0.03807176]
            s = [0.23639539, 0.40126936, 0.49999299, 0.46059387, 0.3987275,  0.34350551,
             0.29873024, 0.26296489, 0.23419652, 0.21075073, 0.19136954]
    
            lifetime_labels = ['0.5ns', '1ns', '2ns', '3ns', '4ns', '5ns', '6ns', '7ns', '8ns', '9ns', '10ns']
    
    
            # series - lifetime labels
            series_lifetime_markers = QtCharts.QScatterSeries()
            for pos in np.arange(len(lifetime_labels)):
                # add label to scene
                label = QGraphicsTextItem(lifetime_labels[pos])
                label.setPos(g[pos], s[pos])
                self.chart.scene().addItem(label)
    
                # add point to chart
                series_lifetime_markers.append(g[pos], s[pos])
                print(f"scene pos {label.scenePos()}")
                print(f"{lifetime_labels[pos]}: {g[pos], s[pos]}")
    
            ''' chart - add series'''
            self.chart.addSeries(series_lifetime_markers)
            # self.chart.createDefaultAxes()
    
            # x_axis
            self.axis_x = QtCharts.QValueAxis()
            self.axis_x.setRange(0, 1)
            self.axis_x.setTickCount(15)
            self.axis_x.setLabelFormat("%.2f")
            self.axis_x.setTitleText("g")
            self.chart.setAxisX(self.axis_x, series_lifetime_markers)
    
            # y_axis
            self.axis_y = QtCharts.QValueAxis()
            self.axis_y.setRange(0, 0.7)
            self.axis_y.setTickCount(15)
            self.axis_y.setLabelFormat("%.2f")
            self.axis_y.setTitleText("s")
            self.chart.setAxisY(self.axis_y, series_lifetime_markers)
    
            ''' LAYOUTS '''
            layout = QVBoxLayout()
            layout.addWidget(self.chartView)
            self.setCentralWidget(QWidget(self))
            self.centralWidget().setLayout(layout)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Chart()
        window.show()
    
        sys.exit(app.exec_())
    
    


  • I think you are setting the labels x and y coordinates too small, g[pos],s[pos] are very small values thats why they all seem to be concentrated near the origin. try to scale your values by setting

    label.setPos(g[pos]*500, s[pos]*500)
    

    Also try editing this to see default labels:

    ''' chart - add series'''
    series_lifetime_markers.setPointLabelsVisible(True)
    self.chart.addSeries(series_lifetime_markers)
    
    

    then you will get what I mean.

    Also you can read up on this



  • @erudite-monkey thanks for taking a look at this. I did come across that post while trying to find an answer. If nothing else works then i'll subclass qchartview and try reimplementing the drawSeriesPointLabels function, but it seems like one of the "mapTo" functions should take care of it, I just can't figure out which one. It looks like the qgraphicstextitem and the qchart are on separate coordinate systems.I did multiply by 500 the g and s values and I can see that it does stretch the values but changing window size resizes the qchart but not the labels, and unfortunately I can't seem to find a way to map label to the qchart coordinates. If using the same coordinate system, the labels should fall right on top of the blue circles.

    0_1565024489141_38feed94-effe-4db5-a6e8-4fabea367bfe-image.png



  • After a couple weeks of trying to figure this out on and off I finally got something working, I'm sure others will benefit from it
    0_1565966889959_labels.PNG

    import sys
    from PySide2.QtUiTools import QUiLoader
    from PySide2.QtWidgets import QApplication, QAction, QFileDialog, QLabel, QLineEdit, \
        QMainWindow, QVBoxLayout, QWidget, QHBoxLayout, QInputDialog, QGraphicsTextItem
    from PySide2.QtCore import QFile, QObject, QPointF
    from PySide2.QtCharts import QtCharts
    from PySide2.QtGui import QPixmap, QImage, QIntValidator, QDoubleValidator, QPainter
    import numpy as np
    
    class Chart(QMainWindow):
        def __init__(self):
            super().__init__()
    
            # chart creation hierarchy:
            # chartview-->charts-->series-->set(or points)
    
            # create chart widget
            self.chart = QtCharts.QChart()
            self.chart.legend().setVisible(False)
            self.chart.setTitle("Phasor Plot")
            self.setGeometry(0, 0, 800, 500)
            self.list_label_graphics_text_item = []
    
            # create chartview
            self.chartView = QtCharts.QChartView(self.chart)
            self.chartView.setRenderHint(QPainter.Antialiasing)
    
            self.chart.scene().changed.connect(self.update_label_position)
    
            self.g = [0.94058736, 0.79830002, 0.49735222, 0.3054408,  0.19831079, 0.1366765,
             0.09905082, 0.074736,   0.0582399,  0.04658614, 0.03807176]
            self.s = [0.23639539, 0.40126936, 0.49999299, 0.46059387, 0.3987275,  0.34350551,
             0.29873024, 0.26296489, 0.23419652, 0.21075073, 0.19136954]
    
            self.lifetime_labels = ['0.5ns', '1ns', '2ns', '3ns', '4ns', '5ns', '6ns', '7ns', '8ns', '9ns', '10ns']
    
    
            # series - lifetime labels
            series_lifetime_markers = QtCharts.QScatterSeries()
            for pos in np.arange(len(self.lifetime_labels)):
                series_lifetime_markers.append(self.g[pos], self.s[pos])
    
    
            ''' chart - add series'''
            self.chart.addSeries(series_lifetime_markers)
    
            # x_axis
            self.axis_x = QtCharts.QValueAxis()
            self.axis_x.setRange(0, 1)
            self.axis_x.setTickCount(15)
            self.axis_x.setLabelFormat("%.2f")
            self.axis_x.setTitleText("g")
            self.chart.setAxisX(self.axis_x, series_lifetime_markers)
    
            # y_axis
            self.axis_y = QtCharts.QValueAxis()
            self.axis_y.setRange(0, 0.7)
            self.axis_y.setTickCount(15)
            self.axis_y.setLabelFormat("%.2f")
            self.axis_y.setTitleText("s")
            self.chart.setAxisY(self.axis_y, series_lifetime_markers)
    
            ''' LAYOUTS '''
            layout = QVBoxLayout()
            layout.addWidget(self.chartView)
            self.setCentralWidget(QWidget(self))
            self.centralWidget().setLayout(layout)
    
        def update_label_position(self):
            ''' position labels over chart '''
            # https://www.qtcentre.org/threads/68981-QChart-QDateTiemAxis-mapTo-and-mapFrom
            # https://stackoverflow.com/questions/44067831/get-mouse-coordinates-in-qchartviews-axis-system
    
            # populate list of labels graphicsTextItems
            if len(self.list_label_graphics_text_item) == 0:
                for pos in np.arange(len(self.g)):  # iterate through g coordinates
                    label = QGraphicsTextItem(self.lifetime_labels[pos])
                    self.list_label_graphics_text_item.append(label)
                    self.chart.scene().addItem(label)
    
            # position the labels
            for pos, label in enumerate(self.list_label_graphics_text_item):
                point_in_series = QPointF(self.g[pos], self.s[pos])  # position in series
                point_series_to_chart = self.chart.mapToPosition(point_in_series, self.chart.series()[0])
                point_chart_to_scene = self.chart.mapToScene(point_series_to_chart)
                label.setPos(point_chart_to_scene)
    
            print(f'{self.lifetime_labels[pos]}: pos in series {point_in_series}\n'
                  f'pos in chart: {point_series_to_chart}\n'
                  f'pos in scene: {point_chart_to_scene}\n')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Chart()
        window.show()
    
        sys.exit(app.exec_())
    
    

Log in to reply