Different Graduated Symbology Class & Color for 100’s of Layers in QGIS

qgissymbology

I have hundreds of layers that I would like to apply a graduated symbology using the Natural Jenks Algorithm for each. If I copy and paste a style for the layer group the classes and colors are the same because it doesn't update the classes or randomly pick a color for the selected layer. I have tried running 'set layer style' as a batch process with a style file (*.qml), but it also produces the same result as the copy/paste method.

Below is the type of result I would like. Each cluster is a separate layer.

enter image description here

Best Answer

We can load a saved qml style and apply it to each layer. While applying it we can modify the Color to be a random values.

The script below works as follows:

  1. Apply the saved .qml style (with jenks etc) to the active layer (change the uri)
  2. Loop through each layer and clone the style to that layer
  3. Modify the Start color variable for each layer, calculate the class breaks, and refresh the layer
from random import randrange

#load source of rendering:
uri = ".../Documents/BelcoStyle.qml"
sourcelayer = iface.activeLayer()
sourcelayer.loadNamedStyle(uri) 
classcount = len([s.color() for s in sourcelayer.renderer().symbols(QgsRenderContext())])
renderer = sourcelayer.renderer()
renderer.updateClasses(sourcelayer,classcount)
print(renderer.sourceColorRamp().color1().getRgb() )
sourcelayer.reload()

i=0
#loop through each layer in the project
for layer in QgsProject.instance().mapLayers().values():
    #ignore not vector layers and the source layer
    if isinstance(layer, QgsVectorLayer)and layer.name()!= sourcelayer.name():
        i+=1
        print('\n'+'RUN:%s, '%str(i)+layer.name())
        #
        #get layers by name
        destlayer = layer
        print(destlayer.name())
        #
        #clone renderer from source layer to current layer
        rendervar= renderer.clone()
        print(rendervar.sourceColorRamp().color1().getRgb() )
        destlayer.setRenderer(rendervar) 
        #
        #CHANGE Start colour randomly
        color1 = QColor (randrange(255), randrange(255), randrange(255))
        color2 = QColor (255, 255, 255)
        destlayer.renderer().updateColorRamp(QgsGradientColorRamp(color1, color2))
        destlayer.renderer().updateClasses(destlayer,classcount)
        print(rendervar.sourceColorRamp().color1().getRgb() )
        destlayer.reload()

iface.mapCanvas().refreshAllLayers()

Input Output Image

Related Question