How to draw a vertical line at specified x value on QHorizontalBarSeries/QChart?

Total
7
Shares

I’ve followed this example to create a horizontal bar chart. I’d like to draw a static vertical line at a specific value along the x-axis. I’ve tried adding a QLineSeries to the QChart, but nothing is showing up. I’m doing this in Python, but C++ works, too.


Solution

A possible solution is to override the drawForeground() method to paint the vertical line, to calculate the positions you must use the mapToPosition() method:

import sys

from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor, QPainter, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtChart import (
    QBarCategoryAxis,
    QBarSet,
    QChart,
    QHorizontalBarSeries,
    QChartView,
    QValueAxis,
)


class ChartView(QChartView):
    _x = None

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, x):
        self._x = x
        self.update()

    def drawForeground(self, painter, rect):
        if self.x is None:
            return
        painter.save()

        pen = QPen(QColor("indigo"))
        pen.setWidth(3)
        painter.setPen(pen)

        p = self.chart().mapToPosition(QPointF(self.x, 0))

        r = self.chart().plotArea()

        p1 = QPointF(p.x(), r.top())
        p2 = QPointF(p.x(), r.bottom())
        painter.drawLine(p1, p2)

        painter.restore()


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

    set0 = QBarSet("Jane")
    set1 = QBarSet("John")
    set2 = QBarSet("Axel")
    set3 = QBarSet("Mary")
    set4 = QBarSet("Samantha")

    set0 << 1 << 2 << 3 << 4 << 5 << 6
    set1 << 5 << 0 << 0 << 4 << 0 << 7
    set2 << 3 << 5 << 8 << 13 << 8 << 5
    set3 << 5 << 6 << 7 << 3 << 4 << 5
    set4 << 9 << 7 << 5 << 3 << 1 << 2

    series = QHorizontalBarSeries()
    series.append(set0)
    series.append(set1)
    series.append(set2)
    series.append(set3)
    series.append(set4)

    chart = QChart()
    chart.addSeries(series)
    chart.setTitle("Simple horizontal barchart example")
    chart.setAnimationOptions(QChart.SeriesAnimations)

    categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
    axisY = QBarCategoryAxis()
    axisY.append(categories)
    chart.addAxis(axisY, Qt.AlignLeft)
    series.attachAxis(axisY)
    axisX = QValueAxis()
    chart.addAxis(axisX, Qt.AlignBottom)
    series.attachAxis(axisX)
    axisX.applyNiceNumbers()

    chart.legend().setVisible(True)
    chart.legend().setAlignment(Qt.AlignBottom)

    chartView = ChartView(chart)
    chartView.setRenderHint(QPainter.Antialiasing)

    chartView.x = 11.5

    window = QMainWindow()
    window.setCentralWidget(chartView)
    window.resize(420, 300)
    window.show()

    app.exec()


if __name__ == "__main__":
    main()

enter image description here

Leave a Reply

Your email address will not be published. Required fields are marked *