[Qgis-user] How to modify (individual) marker properties for a vector layer with many points

afernandez at odyhpc.com afernandez at odyhpc.com
Mon Mar 11 13:34:59 PDT 2024


Hello,
My code is using the following snippet to plot a vector layer:
         vl = QgsVectorLayer("Point", "RadiusField", "memory")
         pr = vl.dataProvider()
         pr.addAttributes([QgsField("name", QVariant.String),
                                    QgsField("radius", QVariant.Double)])
         vl.updateFields()
         for idx in range(self.nx):
             for idy in range(self.ny):
                 f = QgsFeature()
                 
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(self.phalanx[idx,idy,0],self.phalanx[idx,idy,1])))
                 punctum = "point_" + str(idx) + "_" + str(idy)
                 f.setAttributes([punctum, 1.0])
                 pr.addFeature(f)
         vl.updateExtents()
         symbol = QgsMarkerSymbol.createSimple({'name': 'circle', 
'color': 'yellow'})
         vl.renderer().setSymbol(symbol)
         vl.triggerRepaint()
         QgsProject.instance().addMapLayer(vl)
This plots yellow circles of the same radius at all points as expected. 
What I'd like the code to do next is to plot each individual circle with 
specific properties. For example, the following modified snippet tries 
rendering inside the loop:
         vl = QgsVectorLayer("Point", "RadiusField", "memory")
         pr = vl.dataProvider()
         pr.addAttributes([QgsField("name", QVariant.String),
                                    QgsField("radius", QVariant.Double)])
         vl.updateFields()
         for idx in range(self.nx):
             for idy in range(self.ny):
                 f = QgsFeature()
                 
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(self.phalanx[idx,idy,0],self.phalanx[idx,idy,1])))
                 punctum = "point_" + str(idx) + "_" + str(idy)
                 f.setAttributes([punctum, 1.0])
                 pr.addFeature(f)
                 if (idx % 2 == 0) and (idy % 2 == 0):
                     symbol = QgsMarkerSymbol.createSimple({'name': 
'circle', 'color': 'yellow'})
                 elif (idx % 2 == 0):
                     symbol = QgsMarkerSymbol.createSimple({'name': 
'circle', 'color': 'red'})
                 elif (idy % 2 == 0):
                     symbol = QgsMarkerSymbol.createSimple({'name': 
'circle', 'color': 'green'})
                 else:
                     symbol = QgsMarkerSymbol.createSimple({'name': 
'circle', 'color': 'pink'})
                 vl.renderer().setSymbol(symbol)
                 vl.triggerRepaint()
         vl.updateExtents()
         QgsProject.instance().addMapLayer(vl)
However, this results in the same output as it repaints everything with 
the latter symbol (not to mention that replotting the whole vector layer 
over & over becomes expensive).
My main question is whether this is a workable approach (and I need to 
figure out how to render marker by marker) or if I should consider using 
other classes. I was thinking that maybe QgsMarkerSymbolLayer could be 
of use for this problem, but the example from the PyQGIS 
DeveloperCookbook seems to use it for constructing new symbols, not to 
have variations of the same symbol while drawing many of them. Thanks.


More information about the QGIS-User mailing list