1

I currently have a script that runs data within my map and then exports it as a layout in print composer. On the map, I have a legend key that is reference to the data on the map. Within my legend, I have a yellow buffer that is titled 'MM1 1.0 Buffer'. Within the attribute table of this vector file, I have a column called 'LAC_Population_sum', with a value of affected population from an earthquake, within that buffer area. However, I can not seem to find a way to get this value, so it is displayed within my legend on the layout.

The script I use to create a memory buffer is:

# Creating the distance buffers
layer = iface.activeLayer()
feats = [ feat for feat in layer.getFeatures() ]
epsg = layer.crs().postgisSrid()
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer&field=x:real&    field=y:real&field=point_id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                       'MMI 1.0 Buffer',
                       'memory')
prov = mem_layer.dataProvider()

#Adding distance to the buffer
for i, feat in enumerate(feats):
    point = feat.geometry().asPoint()
    new_feat = QgsFeature()
    new_feat.setAttributes([i, point[0], point[1], feat.id()])
    tmp_feat = feat.geometry().buffer(DistInt[1.0], -1) #printing a MMI 1.O Intensity Buffer for a distancethat I have calculated previously and is stored within a dictionary (DistInt)
    new_feat.setGeometry(tmp_feat)
    prov.addFeatures([new_feat])

QgsProject.instance().addMapLayer(mem_layer)

My Attribute table for the MM1 1.0 Buffer, with the value of LAC_Population_sum: enter image description here

What my legend currently shows: enter image description here

My code that creates the LAC_Population_Sum field:

#Using zonal statistics to work out affected population sum column
root = QgsProject.instance().layerTreeRoot()
for layer in root.children():
  if layer.name().startswith('LAC'):
    prefix = layer.name()
    params = {'INPUT_RASTER': layer.name(), 'RASTER_BAND': 1, 'INPUT_VECTOR': 'MMI 1.0 Buffer', 'COLUMN_PREFIX': prefix+'_', 'STATS': 1}
    processing.run("qgis:zonalstatistics", params)
5
  • 2
    Where in your above code do you create the LAC_Population_sum field ? I don't see it. Dec 9 '20 at 12:32
  • Sorry I forgot to include it. I have just edited it now, so it should appear at the bottom of the question.
    – LiamHems
    Dec 9 '20 at 12:42
  • I have tried using the code but it states that the object is not iterable?
    – LiamHems
    Dec 9 '20 at 15:41
  • 1
    If you only have 1 feature you can use this code : attrs = mem_layer.getFeature(0).attributes() value = attrs[mem_layer.fields().indexFromName('LAC_Population_sum')] print(value)
    – JULESG
    Dec 9 '20 at 15:54
  • 1
    @LiamHems: sorry, little mistake. Have you tried : for feat in mem_layer.getFeatures(): print(feat["LAC_Population_sum"]) ? Dec 9 '20 at 16:01
1

You can create a categorized style for your layer so you have the name of the layer and the value of the polygon like this :

enter image description here

You can do it in PyQgis with this code you just need to change the color and opacity in the first 2 lines :

rangeColor = QColor('#ffee00')
opacity = 1
targetField = 'LAC_Population_sum'

attrs = mem_layer.getFeature(0).attributes()
value = attrs[mem_layer.fields().indexFromName(targetField)]

rangeList = []
symbol1 = QgsSymbol.defaultSymbol(mem_layer.geometryType())
symbol1.setColor(rangeColor)
symbol1.setOpacity(opacity)
range1 = QgsRendererCategory(value, symbol1, str(value))
rangeList.append(range1)

groupRenderer = QgsCategorizedSymbolRenderer('', rangeList)
groupRenderer.setClassAttribute(targetField)
mem_layer.setRenderer(groupRenderer)
 

You can also change the name of the layer to obtain something like this :

enter image description here

You can do this with this code :

targetField = 'LAC_Population_sum'

attrs = mem_layer.getFeature(0).attributes()
value = attrs[mem_layer.fields().indexFromName(targetField)]
    
layer_name = mem_layer.sourceName() + " : " + str(value)
mem_layer.setName(layer_name)
4
  • Hi there. Thank you for your reply! I have tried adding the code into my project but unfortunately it comes back with an error for line: value = attrs[mem_layer.fields().indexFromName(targetField)], stating that the list index is out of range. I changed the index value from 0 to 1 and it works, so thank you very much!!
    – LiamHems
    Dec 10 '20 at 12:41
  • If I wanted to change the layer_name so that on my legend, it prints the mem_layer on one line and the + " : " + str(value) on another line? Thanks
    – LiamHems
    Dec 10 '20 at 17:43
  • 1
    @LiamHems you need to add a line break \n so the code looks like this : layer_name = mem_layer.sourceName() + " : \n" + str(value)
    – JULESG
    Dec 11 '20 at 8:11
  • Thank you all works perfectly. I just forgot to put the 'n' after the \ symbol
    – LiamHems
    Dec 11 '20 at 11:04

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.