0

I create multiple QChart() with QLineSeries() and QBarSeries. I like to save the files as pngand svg. The funtion to make the graphs works, but saving the files as svg is different than png.

Result enter image description here

Code to show fault `

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from PyQt5.QtChart import QChart, QChartView, QBarSet, QPercentBarSeries, QBarCategoryAxis, QValueAxis, QBarSeries
from PyQt5.QtGui import QPainter, QFont
from PyQt5.QtCore import Qt, QRectF, QPointF, QSizeF, QSize
from PyQt5.QtSvg import QSvgGenerator

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt BarChart")
        self.setGeometry(100,100, 680,500)
        self.show ()

        barDict = {'TotalRMSV[mm/s]': [2.85], 'barnames': ['2022']}

        chartview = QChartView()
        output_size = QSize (800, 600)  # pixels
        chart = barChart(barDict, "Test")
        chartview.setChart(chart)
        self.setCentralWidget (chartview)
        save_chart_as_svg(chartview,  output_size, "c://temp/test.svg")

def barChart(barDict, graphtitle='barChart'):
    print ("-> qt_graph_tools.barChart")
    series = chart_create_bar_series(barDict)
    axisY = QValueAxis ()

    axisY.setMin(1)                     # If I set Min to 0, all graphics are ok. 
    axisY.setMax(4)

    chart = QChart ()
    chart.addSeries (series)
    chart.setAxisY (axisY, series)

    chart.setTitle (graphtitle)
    chart.setAnimationOptions (QChart.NoAnimation)
    chart.legend ().setAlignment (Qt.AlignBottom)

    return chart

def save_chart_as_svg(chartView, output_size, save_as):
    # the desired size of the rendering
    # in pixels for PNG, in pt for SVG
    output_size.setWidth (int (output_size.width () * 0.75))
    output_size.setHeight (int (output_size.height () * 0.75))   # tranlate pixels to pt
    output_rect = QRectF (QPointF (0, 0), QSizeF (output_size))  # cast to float
    chart = chartView.chart ()
    svg = QSvgGenerator()
    svg.setFileName (save_as)
    svg.setSize (output_size)
    svg.setViewBox (output_rect)
    chart.resize (output_rect.size ())
    painter = QPainter ()
    painter.begin (svg)
    painter.setRenderHint (QPainter.Antialiasing)
    chart.scene ().render (painter, source=output_rect, target=output_rect, mode=Qt.IgnoreAspectRatio)
    painter.end ()
    return svg

def chart_create_bar_series( bardict):
    print("-> qt_graph_tools.chart_create_bar_series")
    series = QBarSeries ()
    for key, data_set in bardict.items():
        if key != 'gear' and key != 'barnames' and key != 'colors':
            barset = QBarSet(key)
            barset.append(data_set)
            series.append(barset)
    return series

App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec_())

`

The image is the resulting SVG shown in Firefox and the Window is its data as QChartView. System: Windows 11, PyQt5.15, python 3.10. If you set the axisY.setMin(0), the output is correct, with higher value it should be cutted at the borderline, but is not. It's not a good idea to set Min fix to 0, because sometimes I'm interested in a range e.g. 5..7

Papageno
  • 305
  • 3
  • 15

0 Answers0