pythonpyqtpyqt5qtchartspyqtchart

QPieChart Legend and Percentage Label


Is it possible in a QPieChart to display the percentages as a label on the circle and the strings in the legend?

Here is my Code for an example

from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from PyQt5.QtChart import QChart, QChartView, QPieSeries, QPieSlice
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
 
        self.setWindowTitle("PyQtChart Pie Chart")
        self.setGeometry(100,100, 1280,600)
 
        self.show()
        self.create_piechart()

    def create_piechart(self):
        series = QtChart.QPieSeries()
        series.append("Python", 80)
        series.append("C++", 70)
        series.append("Java", 50)
        series.append("C#", 40)
        series.append("PHP", 30)
        series.setLabelsVisible(True)
        series.setLabelsPosition(QtChart.QPieSlice.LabelOutside)
        for slice in series.slices():
            slice.setLabel("{:.2f}%".format(100 * slice.percentage()))
 
        chart = QChart()
        chart.legend()
        chart.addSeries(series)
        chart.createDefaultAxes()
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("Pie Chart Example")
 
        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)
        chartview = QChartView(chart)
        chartview.setRenderHint(QPainter.Antialiasing)
 
        self.setCentralWidget(chartview) 
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec_())

Solution

  • In order to show percentages on the pie chart you need to change QPieSeries.

    Change label position from
    series.setLabelsPosition(QtChart.QPieSlice.LabelOutside) to series.setLabelsPosition(QtChart.QPieSlice.LabelInsideHorizontal)

    After that the legend labels are percentages also. To change legend labels modify legend markers

    chart.legend().markers(series)[0].setLabel("Python")
    chart.legend().markers(series)[1].setLabel("C++")
    chart.legend().markers(series)[2].setLabel("Java")
    chart.legend().markers(series)[3].setLabel("C#")
    chart.legend().markers(series)[4].setLabel("PHP")
    

    Result:

    Result

    Link to documentation

    Full Code

    from PyQt5 import QtChart
    from PyQt5.QtWidgets import QApplication, QMainWindow
    import sys
    from PyQt5.QtChart import QChart, QChartView
    from PyQt5.QtGui import QPainter
    from PyQt5.QtCore import Qt
    
    
    class Window(QMainWindow):
        def __init__(self):
            super().__init__()
    
            self.setWindowTitle("PyQtChart Pie Chart")
            self.setGeometry(100, 100, 1280, 600)
    
            self.show()
            self.create_piechart()
    
        def create_piechart(self):
            series = QtChart.QPieSeries()
            series.append("Python", 80)
            series.append("C++", 70)
            series.append("Java", 50)
            series.append("C#", 40)
            series.append("PHP", 30)
            series.setLabelsVisible(True)
    
        
            series.setLabelsPosition(QtChart.QPieSlice.LabelInsideHorizontal)
            for slice in series.slices():
                slice.setLabel("{:.2f}%".format(100 * slice.percentage()))
    
            chart = QChart()
            chart.addSeries(series)
            chart.createDefaultAxes()
            chart.setAnimationOptions(QChart.SeriesAnimations)
            chart.setTitle("Pie Chart Example")
            chart.legend().setVisible(True)
            chart.legend().setAlignment(Qt.AlignBottom)
    
            chart.legend().markers(series)[0].setLabel("Python")
            chart.legend().markers(series)[1].setLabel("C++")
            chart.legend().markers(series)[2].setLabel("Java")
            chart.legend().markers(series)[3].setLabel("C#")
            chart.legend().markers(series)[4].setLabel("PHP")
    
            chartview = QChartView(chart)
            chartview.setRenderHint(QPainter.Antialiasing)
    
            self.setCentralWidget(chartview)
    
    
    if __name__ == '__main__':
        App = QApplication(sys.argv)
        window = Window()
        sys.exit(App.exec_())