viernes, 30 de agosto de 2019

Cómo añadir un diagrama tipo pie (torta) a una capa vectorial con PyQGIS 3

En el post anterior se consideró la adición de un diagrama tipo histograma a una capa vectorial con PyQGIS 3. Como las clases QgsHistogramDiagram y QgsPieDiagram son equivalentes porque presentan los mismos 37 métodos, se vislumbró que la extrapolación del código del referido post anterior era directa mas no fue así. La razón fue un método de la clase QgsLinearlyInterpolatedDiagramRenderer que ha cambiado en PyQGIS 3.

Como no lo sabía, encontré este código que funciona en PyQGIS 2 y lo adapté para PyQGIS 3 de esta manera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Layer
lyr = QgsVectorLayer("/home/zeito/pyqgis_data/County10PopnHou/County10PopnHou.shp", "Population", "ogr")

# Attributes to feature in pie chart symbols
categories = [u'PCT_WHT', u'PCT_BLK', u'PCT_AMIND', u'PCT_ASIAN', u'PCT_HAW', u'PCT_ORA', u'PCT_MR', u'PCT_HISP']

# Colors - 1 for each attribute
colors = ['#3727fa','#01daae','#f849a6','#268605','#6810ff','#453990','#630f2f','#07dd45']

# Convert the colors to Qt QColor objects
qcolors = map(QColor, colors)

# set up our Pie Chart diagram symbol
diagram = QgsPieDiagram()

# Diagram settings
ds = QgsDiagramSettings() 
#ds.font = QFont("Helvetica", 12)
#ds.transparency = 0
ds.categoryColors = qcolors
ds.categoryAttributes = categories
ds.categoryLabels = categories
ds.size = QSizeF(100.0, 100.0)

# Diagram Renderer
dr = QgsLinearlyInterpolatedDiagramRenderer()
dr.setLowerValue(0.0)
dr.setLowerSize(QSizeF(0.0, 0.0))
dr.setUpperValue(2000000)
dr.setUpperSize(QSizeF(40,40))
dr.setClassificationField('P0010001')
dr.setDiagram(diagram)
dr.setDiagramSettings(ds)
lyr.setDiagramRenderer(dr)

# Set layer-wide diagram settings
dls = QgsDiagramLayerSettings()
dls.dist = 0

lyr.setDiagramLayerSettings(dls)

# Delete any cached images and repaint
if hasattr(lyr, "setCacheImage"): 
    lyr.setCacheImage(None)

lyr.triggerRepaint()

## Display the layer and symbols
QgsProject.instance().addMapLayer(lyr)

Su ejecución en la Python Console de QGIS 3.8 produce un resultado similar al de QGIS 2.18:


Por tanto, se adaptó el código del post anterior de la siguiente manera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
layer = iface.activeLayer()

# Set histogram and diagram settings:
hist = QgsPieDiagram()
ds = QgsDiagramSettings()
dColors = {'a1': QColor("cyan"),
           'a2': QColor("red")}
ds.categoryColors = dColors.values()
ds.categoryAttributes = dColors.keys()
ds.categoryLabels = ds.categoryAttributes

# Set renderer:
renderer = QgsLinearlyInterpolatedDiagramRenderer()
renderer.setUpperValue(1)  # Here you should set the maximum value of both attributes
renderer.setUpperSize(QSizeF(10, 10))
renderer.setClassificationField('a2')
renderer.setDiagram(hist)
renderer.setDiagramSettings(ds)

# Set diagram layer settings:
layer.setDiagramRenderer(renderer)
dls = QgsDiagramLayerSettings()

layer.setDiagramLayerSettings(dls)
layer.triggerRepaint()

La ejecucion del código anterior produjo el resultado esperado; tal como se presenta en la imagen siguiente.


No hay comentarios: