0

I have used code from previous post to create pie charts. I manage to display the pie graphs after going into properties and setting find to Maximum Value. Though this is not happening automatically when rendering with my code.

enter image description here

The uppervalue must also be calculated from the maximum value from all my attributes that is passed in as an expression.

Lastly, is there also a way to autogenerate the colors for each field? I don't want to manually add the code for each variable each time I run this script since these fields might change in the future.

from qgis.PyQt.QtCore import QVariant

import os # This is is needed in the pyqgis console also
from qgis.core import (
    QgsVectorLayer
)


pointFile = ".../Site Location.shp"



Layer = QgsVectorLayer(pointFile, 'Site Location', 'ogr')


    
diagram = QgsPieDiagram()

ds = QgsDiagramSettings()

dColors = {'Field1': QColor('#ff0000'),
                    'Field2': QColor('#00ff00'),
                    'Field3': QColor('#0000ff'),
                    'Field4': QColor('#d2b4de')}


ds.categoryColors = dColors.values()
ds.categoryAttributes = dColors.keys()
ds.categoryLabels = ds.categoryAttributes

dr = QgsLinearlyInterpolatedDiagramRenderer()
dr.setLowerValue(0.0)
dr.setLowerSize(QSizeF(0.0,0.0))
dr.setUpperValue(46)  # Here you should set the maximum value of both attributes
dr.setUpperSize(QSizeF(10, 10))
strExp = ' "Field1"  +  "Field2"+ "Field3" + "Field4"'
dr.setClassificationField(strExp)

dr.setDiagram(diagram)

dr.setDiagramSettings(ds)
Layer.setDiagramRenderer(dr)

# Set diagram layer settings:
dls = QgsDiagramLayerSettings()
dls.dist = 0
dls.priority = 0
dls.xPosColumn = -1
dls.yPosColumn = -1
dls.placement = 0

Layer.setDiagramLayerSettings(dls)

label_settings = QgsPalLayerSettings()
Layer.setLabeling(QgsVectorLayerSimpleLabeling(label_settings))
Layer.setLabelsEnabled(True)
Layer.triggerRepaint()

QgsProject.instance().addMapLayer(Layer)

0

Two points:

Look at the following methods as I'm not sure you should use setClassificationField (PS: not certain as only supposed from the API doc)

dr.setClassificationAttributeExpression(strExp)
dr.setClassificationAttributeIsExpression(True)

The part that calculate the value for the "Find" button should be the following. It's a port of the C++ code e.g https://github.com/qgis/QGIS/blob/master/src/gui/vector/qgsdiagramproperties.cpp#L704

maxValue = 0.0;
exp = QgsExpression(strExp)
context = QgsExpressionContext()

context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance()))
context.appendScope(QgsExpressionContextUtils.mapSettingsScope(iface.mapCanvas().mapSettings()))
context.appendScope(QgsExpressionContextUtils.layerScope(Layer))

exp.prepare(context)
if (not exp.hasEvalError()):
    feature = QgsFeature()
    features = Layer.getFeatures()
    while features.nextFeature(feature):
        context.setFeature(feature);
        maxValue = max(maxValue, float(exp.evaluate(context)));
# Use the maxValue to set the upper value
dr.setUpperValue(maxValue)
| improve this answer | |
  • Hi thanks this code solved my problem. Thanks!!! I originally saw the setClassificationAttributeExpression and setClassificationAttributeIsExpression methods, I didn't realize they need to be used together. I struggle with understanding the documentation sometimes. I guess I'll get better in time. Thanks a lot! – Colette de Villiers Jun 15 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.