QGIS Symbology – Setting Symbol Sizes for a Graduated Layer in QGIS 3

classificationpyqgisqgisqgis-3symbology

I have a whole set of maps that have graduated colors based on a set ramp and I also like to change the symbol sizes as it makes anomalous areas stand out even more.
Id like to change the symbol sizes with the console (if I use the automatic classification by value the symbol sizes are reset).

In QGIS 2.18 I could do it by:

layer = qgis.utils.iface.mapCanvas().currentLayer()
symbols = layer.rendererV2().symbols()
symbols[0].setSize(1.5)
symbols[1].setSize(1.75)
symbols[2].setSize(2)
symbols[3].setSize(2.25)
symbols[4].setSize(2.5)
symbols[5].setSize(2.75)

In QGIS 3 the rendererV2 has been renamed (to renderer), but I am stuck on how to call the symbols. I know its likely a python 3 syntax I am missing, but it hangs on

symbols = layer.rendererV2().symbols()

TypeError: symbols(self, context: QgsRenderContext): not enough arguments

I did manage to get at the symbols a different way:

layer = qgis.utils.iface.mapCanvas().currentLayer()
renderer = layer.renderer()
renderer.ranges()[1].symbol().size()
ranges = renderer.ranges()
ranges[0].symbol().size()

but if I do:

ranges[0].symbol().setSize(1.5)

it does not actually change anything and a layer refresh does not help. If I query the size again it tells me the original size, and I guess it is the default value the graduated renderer is using.

In the change log for v3, QgsSymbolLayer (renamed from QgsSymbolLayerV2) says usedAttributes() now requires a QgsRenderContext argument.
I've been poking at this for a long time and I feel I am close, but I just am not familiar enough with python to get over this hurdle.

QGIS API

Best Answer

In 3.0 you'd need to make a copy of the existing symbol, edit it, and then save it back to the renderer:

renderer = layer.renderer()
# get the current symbol
range = renderer.ranges()[1]
current_symbol = range.symbol()
# make a new copy of it
new_symbol = current_symbol.clone()
# edit the symbol properties
new_symbol.setSize(1.5)
# save it back to the graduated class
renderer.updateRangeSymbol(1, new_symbol)
Related Question