[{"data":1,"prerenderedAt":1117},["ShallowReactive",2],{"doc:\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fset-layer-opacity-and-blend-mode-pyqgis":3},{"id":4,"title":5,"body":6,"description":1106,"extension":1107,"meta":1108,"navigation":218,"path":1113,"seo":1114,"stem":1115,"__hash__":1116},"docs\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fset-layer-opacity-and-blend-mode-pyqgis\u002Findex.md","Set Layer Opacity and Blend Modes in PyQGIS",{"type":7,"value":8,"toc":1093},"minimark",[9,13,17,26,150,155,177,181,184,263,277,280,328,333,337,340,396,408,414,418,421,468,501,504,553,574,669,673,676,679,685,755,768,772,779,829,846,850,856,947,951,1001,1005,1015,1019,1025,1035,1044,1055,1059,1089],[10,11,5],"h1",{"id":12},"set-layer-opacity-and-blend-modes-in-pyqgis",[14,15,16],"p",{},"Transparency in QGIS is not one setting. There is the opacity of the whole rendered layer, the alpha channel of a symbol's colour, the opacity of an individual symbol layer, and — separate from all three — the blend mode that decides arithmetic rather than mixing. Choosing the wrong one produces a map that is nearly right and stubbornly refuses to be fixed by adjusting a number.",[14,18,19,20,25],{},"This recipe belongs to ",[21,22,24],"a",{"href":23},"\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002F","Symbol Layers & Advanced Symbology in PyQGIS",". It covers each level from Python, the blend modes worth knowing by name, the difference between layer blending and feature blending, and what happens to all of it when the map is exported to PDF.",[14,27,28],{},[29,30,35,39,43,50,67,76,86,92,100,103,107,112,117,121,135,142,145],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 320","img","Four levels of transparency in QGIS compared: colour alpha applied per primitive, symbol layer opacity, symbol opacity, and layer opacity applied to the finished render","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"Where transparency is applied in the render pipeline",[40,41,42],"desc",{},"Colour alpha applies as each primitive is painted, so overlapping features accumulate and read darker. Symbol layer and symbol opacity apply to that symbol's own output. Layer opacity applies once to the finished flattened layer, so overlaps within the layer do not accumulate.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","320","#f6f3ea",[51,52,53],"defs",{},[54,55,62],"marker",{"id":56,"viewBox":57,"refX":58,"refY":59,"markerWidth":60,"markerHeight":60,"orient":61},"opArrow","0 0 10 10","8","5","7","auto-start-reverse",[63,64],"path",{"d":65,"fill":66},"M0 0 L10 5 L0 10 z","#2f3b35",[68,69,75],"text",{"x":70,"y":71,"style":72,"fill":73,"textAnchor":74},"380","28","text-anchor:middle;font-size:14px;font-weight:bold;font-family:sans-serif","#17211d","middle","Overlaps accumulate — unless the fade is applied last",[44,77],{"x":78,"y":79,"width":80,"height":81,"rx":82,"fill":83,"stroke":84,"style":85},"30","54","330","220","10","#fdf2e2","#b45309","stroke-width:2.5",[68,87,91],{"x":88,"y":89,"style":90,"fill":84,"textAnchor":74},"195","80","text-anchor:middle;font-size:12.5px;font-weight:bold;font-family:sans-serif","colour alpha, per primitive",[93,94],"circle",{"cx":95,"cy":96,"r":97,"fill":98,"fillOpacity":99},"150","160","46","#2563eb",0.4,[93,101],{"cx":102,"cy":96,"r":97,"fill":98,"fillOpacity":99},"210",[93,104],{"cx":105,"cy":106,"r":97,"fill":98,"fillOpacity":99},"180","206",[68,108,111],{"x":88,"y":109,"style":110,"fill":66,"textAnchor":74},"264","text-anchor:middle;font-size:11px;font-family:sans-serif","where three overlap it is nearly solid",[44,113],{"x":114,"y":79,"width":80,"height":81,"rx":82,"fill":115,"stroke":116,"style":85},"400","#edf8e9","#15803d",[68,118,120],{"x":119,"y":89,"style":90,"fill":116,"textAnchor":74},"565","layer opacity, applied once",[122,123,124,127,130,133],"g",{"fillOpacity":99},[93,125],{"cx":126,"cy":96,"r":97,"fill":98},"520",[93,128],{"cx":129,"cy":96,"r":97,"fill":98},"580",[93,131],{"cx":132,"cy":106,"r":97,"fill":98},"550",[93,134],{"cx":126,"cy":96,"r":97,"fill":98},[44,136],{"x":137,"y":138,"width":139,"height":140,"fill":49,"fillOpacity":141},"474","114","152","138",0,[68,143,144],{"x":119,"y":109,"style":110,"fill":66,"textAnchor":74},"the layer is flattened, then faded evenly",[68,146,149],{"x":70,"y":147,"style":110,"fill":148,"textAnchor":74},"306","#59645f","same three circles, same 40 percent, two different maps",[151,152,154],"h2",{"id":153},"prerequisites","Prerequisites",[156,157,158,166,169],"ul",{},[159,160,161,165],"li",{},[162,163,164],"strong",{},"QGIS 3.34 LTR"," (bundled Python 3.12) or newer.",[159,167,168],{},"At least two overlapping layers if you want to see blend modes do anything — the canonical pair is a hillshade under a thematic fill.",[159,170,171,172,176],{},"A basic stacked symbol; see ",[21,173,175],{"href":174},"\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fstack-symbol-layers-pyqgis\u002F","stacking symbol layers"," if the layers in a symbol are new to you.",[151,178,180],{"id":179},"layer-opacity-fade-the-finished-render","Layer opacity: fade the finished render",[14,182,183],{},"The simplest control fades everything the layer drew, after it drew it.",[185,186,191],"pre",{"className":187,"code":188,"language":189,"meta":190,"style":190},"language-python shiki shiki-themes github-dark","from qgis.core import QgsProject\n\nlayer = QgsProject.instance().mapLayersByName(\"landuse\")[0]\nlayer.setOpacity(0.55)\nlayer.triggerRepaint()\n","python","",[192,193,194,213,220,245,257],"code",{"__ignoreMap":190},[195,196,199,203,207,210],"span",{"class":197,"line":198},"line",1,[195,200,202],{"class":201},"snl16","from",[195,204,206],{"class":205},"s95oV"," qgis.core ",[195,208,209],{"class":201},"import",[195,211,212],{"class":205}," QgsProject\n",[195,214,216],{"class":197,"line":215},2,[195,217,219],{"emptyLinePlaceholder":218},true,"\n",[195,221,223,226,229,232,236,239,242],{"class":197,"line":222},3,[195,224,225],{"class":205},"layer ",[195,227,228],{"class":201},"=",[195,230,231],{"class":205}," QgsProject.instance().mapLayersByName(",[195,233,235],{"class":234},"sU2Wk","\"landuse\"",[195,237,238],{"class":205},")[",[195,240,46],{"class":241},"sDLfK",[195,243,244],{"class":205},"]\n",[195,246,248,251,254],{"class":197,"line":247},4,[195,249,250],{"class":205},"layer.setOpacity(",[195,252,253],{"class":241},"0.55",[195,255,256],{"class":205},")\n",[195,258,260],{"class":197,"line":259},5,[195,261,262],{"class":205},"layer.triggerRepaint()\n",[14,264,265,268,269,272,273,276],{},[162,266,267],{},"Breakdown:"," ",[192,270,271],{},"setOpacity()"," takes a float from 0 to 1 and applies to the layer's composited output, so a polygon that overlaps another polygon in the same layer does not double up. That property is exactly what you want for a thematic wash over a basemap, and exactly what you do not want when the overlap itself carries meaning. Note that this replaced the older ",[192,274,275],{},"setLayerTransparency(int)"," — a percentage, and inverted — which was removed in QGIS 3.",[14,278,279],{},"Raster layers use the same call, but their renderer also has an opacity, and the two multiply:",[185,281,283],{"className":187,"code":282,"language":189,"meta":190,"style":190},"raster = QgsProject.instance().mapLayersByName(\"hillshade\")[0]\nraster.renderer().setOpacity(0.8)\nraster.setOpacity(0.9)                # net 0.72\n",[192,284,285,303,313],{"__ignoreMap":190},[195,286,287,290,292,294,297,299,301],{"class":197,"line":198},[195,288,289],{"class":205},"raster ",[195,291,228],{"class":201},[195,293,231],{"class":205},[195,295,296],{"class":234},"\"hillshade\"",[195,298,238],{"class":205},[195,300,46],{"class":241},[195,302,244],{"class":205},[195,304,305,308,311],{"class":197,"line":215},[195,306,307],{"class":205},"raster.renderer().setOpacity(",[195,309,310],{"class":241},"0.8",[195,312,256],{"class":205},[195,314,315,318,321,324],{"class":197,"line":222},[195,316,317],{"class":205},"raster.setOpacity(",[195,319,320],{"class":241},"0.9",[195,322,323],{"class":205},")                ",[195,325,327],{"class":326},"sjoCn","# net 0.72\n",[14,329,330,332],{},[162,331,267],{}," Setting both is legal and almost always a mistake, because the number you tune afterwards is not the number you see. Pick one — the layer for a simple fade, the renderer when a specific band's rendering needs to be dialled back independently of the layer.",[151,334,336],{"id":335},"colour-alpha-fade-each-drawn-shape","Colour alpha: fade each drawn shape",[14,338,339],{},"When overlaps should accumulate, put the transparency in the colour instead.",[185,341,343],{"className":187,"code":342,"language":189,"meta":190,"style":190},"from qgis.PyQt.QtGui import QColor\n\ncolour = QColor(\"#2563eb\")\ncolour.setAlphaF(0.35)\nlayer.renderer().symbol().setColor(colour)\nlayer.triggerRepaint()\n",[192,344,345,357,361,376,386,391],{"__ignoreMap":190},[195,346,347,349,352,354],{"class":197,"line":198},[195,348,202],{"class":201},[195,350,351],{"class":205}," qgis.PyQt.QtGui ",[195,353,209],{"class":201},[195,355,356],{"class":205}," QColor\n",[195,358,359],{"class":197,"line":215},[195,360,219],{"emptyLinePlaceholder":218},[195,362,363,366,368,371,374],{"class":197,"line":222},[195,364,365],{"class":205},"colour ",[195,367,228],{"class":201},[195,369,370],{"class":205}," QColor(",[195,372,373],{"class":234},"\"#2563eb\"",[195,375,256],{"class":205},[195,377,378,381,384],{"class":197,"line":247},[195,379,380],{"class":205},"colour.setAlphaF(",[195,382,383],{"class":241},"0.35",[195,385,256],{"class":205},[195,387,388],{"class":197,"line":259},[195,389,390],{"class":205},"layer.renderer().symbol().setColor(colour)\n",[195,392,394],{"class":197,"line":393},6,[195,395,262],{"class":205},[14,397,398,268,400,403,404,407],{},[162,399,267],{},[192,401,402],{},"setAlphaF()"," takes 0–1; ",[192,405,406],{},"setAlpha()"," takes 0–255, and mixing them up is the reason a symbol occasionally comes out invisible. Because the alpha is on the brush, each drawn feature blends with whatever is already on the canvas — including earlier features from the same layer. Density maps of overlapping buffers rely on this, and it is a genuinely different picture from the same value applied as layer opacity.",[14,409,410,413],{},[192,411,412],{},"symbol.setOpacity(0.35)"," sits between the two: it fades the whole symbol including all of its symbol layers, but still per feature, so overlaps still accumulate.",[151,415,417],{"id":416},"blend-modes-arithmetic-not-mixing","Blend modes: arithmetic, not mixing",[14,419,420],{},"A blend mode replaces \"put this on top\" with a per-channel calculation between the incoming pixel and what is already there.",[185,422,424],{"className":187,"code":423,"language":189,"meta":190,"style":190},"from qgis.PyQt.QtGui import QPainter\n\nthematic = QgsProject.instance().mapLayersByName(\"landuse\")[0]\nthematic.setBlendMode(QPainter.CompositionMode_Multiply)\nthematic.triggerRepaint()\n",[192,425,426,437,441,458,463],{"__ignoreMap":190},[195,427,428,430,432,434],{"class":197,"line":198},[195,429,202],{"class":201},[195,431,351],{"class":205},[195,433,209],{"class":201},[195,435,436],{"class":205}," QPainter\n",[195,438,439],{"class":197,"line":215},[195,440,219],{"emptyLinePlaceholder":218},[195,442,443,446,448,450,452,454,456],{"class":197,"line":222},[195,444,445],{"class":205},"thematic ",[195,447,228],{"class":201},[195,449,231],{"class":205},[195,451,235],{"class":234},[195,453,238],{"class":205},[195,455,46],{"class":241},[195,457,244],{"class":205},[195,459,460],{"class":197,"line":247},[195,461,462],{"class":205},"thematic.setBlendMode(QPainter.CompositionMode_Multiply)\n",[195,464,465],{"class":197,"line":259},[195,466,467],{"class":205},"thematic.triggerRepaint()\n",[14,469,470,268,472,475,476,478,479,482,483,486,487,490,491,486,494,497,498,500],{},[162,471,267],{},[192,473,474],{},"Multiply"," darkens: each channel is multiplied, so white leaves the underlying pixel alone and anything darker shades it. Laid over a hillshade this produces relief-shaded thematic mapping with no manual work, and it is the reason ",[192,477,474],{}," is by far the most used mode in QGIS. ",[192,480,481],{},"Screen"," is the inverse and lightens; ",[192,484,485],{},"Darken"," and ",[192,488,489],{},"Lighten"," pick the extreme per channel rather than combining; ",[192,492,493],{},"Overlay",[192,495,496],{},"SoftLight"," boost contrast and are worth trying when ",[192,499,474],{}," makes a map too heavy.",[14,502,503],{},"The same call exists at symbol-layer level, which is how one layer of a stack can multiply onto the layer beneath it inside a single symbol:",[185,505,507],{"className":187,"code":506,"language":189,"meta":190,"style":190},"from qgis.core import QgsProject\n\nsymbol = thematic.renderer().symbol()\nsymbol.symbolLayer(1).setRenderingPass(1)\nthematic.setFeatureBlendMode(QPainter.CompositionMode_Darken)\n",[192,508,509,519,523,533,548],{"__ignoreMap":190},[195,510,511,513,515,517],{"class":197,"line":198},[195,512,202],{"class":201},[195,514,206],{"class":205},[195,516,209],{"class":201},[195,518,212],{"class":205},[195,520,521],{"class":197,"line":215},[195,522,219],{"emptyLinePlaceholder":218},[195,524,525,528,530],{"class":197,"line":222},[195,526,527],{"class":205},"symbol ",[195,529,228],{"class":201},[195,531,532],{"class":205}," thematic.renderer().symbol()\n",[195,534,535,538,541,544,546],{"class":197,"line":247},[195,536,537],{"class":205},"symbol.symbolLayer(",[195,539,540],{"class":241},"1",[195,542,543],{"class":205},").setRenderingPass(",[195,545,540],{"class":241},[195,547,256],{"class":205},[195,549,550],{"class":197,"line":259},[195,551,552],{"class":205},"thematic.setFeatureBlendMode(QPainter.CompositionMode_Darken)\n",[14,554,555,268,557,560,561,565,566,569,570,573],{},[162,556,267],{},[192,558,559],{},"setFeatureBlendMode()"," blends features of ",[562,563,564],"em",{},"this"," layer against each other rather than against the layers below, which is the tool for showing where features of one layer overlap without them also darkening the basemap. ",[192,567,568],{},"setRenderingPass()"," shifts a symbol layer into a later pass so it draws after every feature's earlier passes, which is how a casing can be drawn under ",[562,571,572],{},"all"," the roads rather than under each road individually — the fix for the classic \"roads casing cuts across the junction\" artefact.",[14,575,576],{},[29,577,580,583,586,589,592,608,615,621,628,632,636,639,641,644,647,650,653,656,659,662,665],{"viewBox":578,"role":32,"ariaLabel":579,"xmlns":34},"0 0 760 300","Three blend modes applied to the same thematic fill over a hillshade: normal hides the relief, multiply darkens and reveals it, and screen lightens",[36,581,582],{},"Multiply is the mode that reveals relief",[40,584,585],{},"The same coloured fill sits over the same shaded relief. With normal compositing the fill covers the relief entirely. With multiply the relief shows through as shading within the colour. With screen the result lightens and the relief is present but washed out.",[44,587],{"x":46,"y":46,"width":47,"height":588,"fill":49},"300",[68,590,591],{"x":70,"y":71,"style":72,"fill":73,"textAnchor":74},"Same two layers, three compositing rules",[51,593,594],{},[595,596,598,602,606],"linear-gradient",{"id":597,"x1":46,"y1":46,"x2":540,"y2":540},"reliefA",[599,600],"stop",{"offset":46,"stopColor":601},"#e7e2d4",[599,603],{"offset":604,"stopColor":605},"0.5","#b8b1a0",[599,607],{"offset":540,"stopColor":601},[44,609],{"x":610,"y":79,"width":611,"height":612,"rx":82,"fill":613,"stroke":614,"style":85},"26","216","196","#fffdf7","#b91c1c",[68,616,620],{"x":617,"y":618,"style":619,"fill":614,"textAnchor":74},"134","78","text-anchor:middle;font-size:12px;font-weight:bold;font-family:sans-serif","Normal",[44,622],{"x":623,"y":624,"width":625,"height":626,"fill":627},"50","92","168","112","url(#reliefA)",[44,629],{"x":623,"y":624,"width":625,"height":626,"fill":630,"fillOpacity":631},"#0f766e",0.85,[68,633,635],{"x":617,"y":634,"style":110,"fill":66,"textAnchor":74},"228","the relief is gone",[44,637],{"x":638,"y":79,"width":611,"height":612,"rx":82,"fill":613,"stroke":116,"style":85},"272",[68,640,474],{"x":70,"y":618,"style":619,"fill":116,"textAnchor":74},[44,642],{"x":643,"y":624,"width":625,"height":626,"fill":627},"296",[44,645],{"x":643,"y":624,"width":625,"height":626,"fill":630,"style":646},"mix-blend-mode:multiply",[68,648,649],{"x":70,"y":634,"style":110,"fill":66,"textAnchor":74},"colour plus shading",[44,651],{"x":652,"y":79,"width":611,"height":612,"rx":82,"fill":613,"stroke":84,"style":85},"518",[68,654,481],{"x":655,"y":618,"style":619,"fill":84,"textAnchor":74},"626",[44,657],{"x":658,"y":624,"width":625,"height":626,"fill":627},"542",[44,660],{"x":658,"y":624,"width":625,"height":626,"fill":630,"style":661},"mix-blend-mode:screen",[68,663,664],{"x":655,"y":634,"style":110,"fill":66,"textAnchor":74},"present but washed out",[68,666,668],{"x":70,"y":667,"style":110,"fill":148,"textAnchor":74},"284","multiply leaves white untouched, which is why it works over a hillshade",[151,670,672],{"id":671},"choosing-between-the-four-levels","Choosing between the four levels",[14,674,675],{},"Written as a decision, the choice is short.",[14,677,678],{},"If the whole layer should sit back so something beneath it reads through, use layer opacity. If overlapping features within the layer should build up — overlapping buffers, stacked catchments, repeated GPS tracks — use colour alpha. If one part of a stacked symbol should fade while the rest stays solid, use symbol-layer opacity. If the effect you want is shading, tinting or contrast rather than transparency at all, you want a blend mode and no opacity anywhere.",[14,680,681,682,684],{},"A worked case makes the distinction concrete. Say a flood-extent layer must show both where water reaches and how many scenarios agree. Layer opacity gives a uniform blue wash that answers the first question and destroys the second. Colour alpha at 25 percent answers both: one scenario is faint, four overlapping scenarios are strong, and the reader gets a density map for free. Add ",[192,683,474],{}," on top of a hillshade and the same layer also shows the terrain the water is sitting in — three pieces of information from one fill, and none of them needed a second layer.",[185,686,688],{"className":187,"code":687,"language":189,"meta":190,"style":190},"from qgis.PyQt.QtGui import QColor, QPainter\n\nwater = QColor(\"#2563eb\")\nwater.setAlphaF(0.25)\nflood.renderer().symbol().setColor(water)\nflood.setBlendMode(QPainter.CompositionMode_Multiply)\nflood.setOpacity(1.0)\nflood.triggerRepaint()\n",[192,689,690,701,705,718,728,733,738,749],{"__ignoreMap":190},[195,691,692,694,696,698],{"class":197,"line":198},[195,693,202],{"class":201},[195,695,351],{"class":205},[195,697,209],{"class":201},[195,699,700],{"class":205}," QColor, QPainter\n",[195,702,703],{"class":197,"line":215},[195,704,219],{"emptyLinePlaceholder":218},[195,706,707,710,712,714,716],{"class":197,"line":222},[195,708,709],{"class":205},"water ",[195,711,228],{"class":201},[195,713,370],{"class":205},[195,715,373],{"class":234},[195,717,256],{"class":205},[195,719,720,723,726],{"class":197,"line":247},[195,721,722],{"class":205},"water.setAlphaF(",[195,724,725],{"class":241},"0.25",[195,727,256],{"class":205},[195,729,730],{"class":197,"line":259},[195,731,732],{"class":205},"flood.renderer().symbol().setColor(water)\n",[195,734,735],{"class":197,"line":393},[195,736,737],{"class":205},"flood.setBlendMode(QPainter.CompositionMode_Multiply)\n",[195,739,741,744,747],{"class":197,"line":740},7,[195,742,743],{"class":205},"flood.setOpacity(",[195,745,746],{"class":241},"1.0",[195,748,256],{"class":205},[195,750,752],{"class":197,"line":751},8,[195,753,754],{"class":205},"flood.triggerRepaint()\n",[14,756,757,759,760,763,764,767],{},[162,758,267],{}," Leaving ",[192,761,762],{},"setOpacity(1.0)"," explicit is worth the line — it documents that the fade is deliberately in the colour, and it resets the layer if an earlier experiment left an opacity behind. The order of the three calls does not matter, because none of them render; only ",[192,765,766],{},"triggerRepaint()"," does, and it should be the last statement in any styling block for exactly that reason.",[151,769,771],{"id":770},"the-export-caveat","The export caveat",[14,773,774,775,778],{},"Blend modes other than ",[192,776,777],{},"SourceOver"," cannot be expressed in PDF or SVG. QGIS deals with this by rasterising any layer that uses one, which means a print layout containing a multiplied fill exports a raster tile for that layer while everything else stays vector.",[185,780,782],{"className":187,"code":781,"language":189,"meta":190,"style":190},"from qgis.core import QgsLayoutExporter\n\nsettings = QgsLayoutExporter.PdfExportSettings()\nsettings.rasterizeWholeImage = False\nsettings.forceVectorOutput = True\n",[192,783,784,795,799,809,819],{"__ignoreMap":190},[195,785,786,788,790,792],{"class":197,"line":198},[195,787,202],{"class":201},[195,789,206],{"class":205},[195,791,209],{"class":201},[195,793,794],{"class":205}," QgsLayoutExporter\n",[195,796,797],{"class":197,"line":215},[195,798,219],{"emptyLinePlaceholder":218},[195,800,801,804,806],{"class":197,"line":222},[195,802,803],{"class":205},"settings ",[195,805,228],{"class":201},[195,807,808],{"class":205}," QgsLayoutExporter.PdfExportSettings()\n",[195,810,811,814,816],{"class":197,"line":247},[195,812,813],{"class":205},"settings.rasterizeWholeImage ",[195,815,228],{"class":201},[195,817,818],{"class":241}," False\n",[195,820,821,824,826],{"class":197,"line":259},[195,822,823],{"class":205},"settings.forceVectorOutput ",[195,825,228],{"class":201},[195,827,828],{"class":241}," True\n",[14,830,831,268,833,836,837,840,841,845],{},[162,832,267],{},[192,834,835],{},"forceVectorOutput = True"," asks QGIS to keep vectors where it can, but it cannot override the blend-mode rule — the affected layer still rasterises, and the rest of the layout stays sharp. ",[192,838,839],{},"rasterizeWholeImage = True"," is the blunt alternative that flattens everything, producing a file that always matches the canvas at the cost of selectable text and scalable line work. When crisp vector output matters more than the effect, bake the shading into the data instead: multiply the hillshade into the thematic raster once with the ",[21,842,844],{"href":843},"\u002Fspatial-data-processing-automation\u002Fraster-analysis-workflows\u002Fraster-calculator-pyqgis\u002F","raster calculator"," and style the result normally.",[151,847,849],{"id":848},"qgis-version-compatibility","QGIS version compatibility",[14,851,852,853,855],{},"The examples target ",[162,854,164],{}," (Python 3.12).",[857,858,859,875],"table",{},[860,861,862],"thead",{},[863,864,865,869,872],"tr",{},[866,867,868],"th",{},"QGIS version",[866,870,871],{},"Python",[866,873,874],{},"Notes",[876,877,878,898,916,926,937],"tbody",{},[863,879,880,884,887],{},[881,882,883],"td",{},"3.16 LTR",[881,885,886],{},"3.7",[881,888,889,891,892,486,895,897],{},[192,890,271],{}," on layers, ",[192,893,894],{},"setBlendMode()",[192,896,559],{}," all present.",[863,899,900,903,906],{},[881,901,902],{},"3.22 LTR",[881,904,905],{},"3.9",[881,907,908,909,486,912,915],{},"Layout export settings expose ",[192,910,911],{},"forceVectorOutput",[192,913,914],{},"rasterizeWholeImage",".",[863,917,918,921,923],{},[881,919,920],{},"3.28 LTR",[881,922,905],{},[881,924,925],{},"Raster renderer opacity independent of layer opacity.",[863,927,928,931,934],{},[881,929,930],{},"3.34 LTR",[881,932,933],{},"3.12",[881,935,936],{},"Baseline for this page.",[863,938,939,942,944],{},[881,940,941],{},"3.40+",[881,943,933],{},[881,945,946],{},"Blend modes selectable on individual symbol layers in the GUI as well as the API.",[151,948,950],{"id":949},"troubleshooting","Troubleshooting",[156,952,953,962,970,983,989,995],{},[159,954,955,958,959,915],{},[162,956,957],{},"Overlaps look solid when you wanted a wash."," Colour alpha is accumulating. Move the transparency to ",[192,960,961],{},"layer.setOpacity()",[159,963,964,967,968,915],{},[162,965,966],{},"The wash is uniform when you wanted density."," The reverse — move the transparency into the colour with ",[192,969,402],{},[159,971,972,268,975,978,979,982],{},[162,973,974],{},"A symbol vanished entirely.",[192,976,977],{},"setAlpha(0.35)"," was used instead of ",[192,980,981],{},"setAlphaF(0.35)","; on the 0–255 scale, 0.35 rounds to zero.",[159,984,985,988],{},[162,986,987],{},"Multiply has no visible effect."," There is nothing beneath the layer to multiply with, or the layer below is also using a blend mode and the order is fighting you. Check the layer tree order.",[159,990,991,994],{},[162,992,993],{},"The PDF has a fuzzy patch where one layer was."," That layer uses a blend mode and was rasterised. Bake the effect into the data or accept the raster.",[159,996,997,1000],{},[162,998,999],{},"Opacity does not stick after reopening the project."," The change was made on a layer object that was replaced on reload. Set it in a project-loaded hook, or save the style with the project.",[151,1002,1004],{"id":1003},"conclusion","Conclusion",[14,1006,1007,1008,1010,1011,1014],{},"Use ",[192,1009,961],{}," to fade a finished layer evenly, colour alpha when overlaps should accumulate, and ",[192,1012,1013],{},"setBlendMode(QPainter.CompositionMode_Multiply)"," to shade a thematic fill with relief. Remember that any blend mode other than the default forces that layer to rasterise on PDF and SVG export, and bake the effect into the data when vector output matters more.",[151,1016,1018],{"id":1017},"frequently-asked-questions","Frequently Asked Questions",[14,1020,1021,1024],{},[162,1022,1023],{},"What is the difference between blend mode and feature blend mode?","\nBlend mode composites this layer against everything already drawn beneath it. Feature blend mode composites this layer's own features against each other before the layer as a whole is composited. Use the second when you want to show self-overlap without darkening the basemap.",[14,1026,1027,1030,1031,1034],{},[162,1028,1029],{},"Can I set a blend mode on one symbol layer only?","\nYes — ",[192,1032,1033],{},"symbol_layer.setBlendMode()"," — and it composites that layer against the earlier layers of the same symbol. It is the neatest way to make a highlight glow blend into its own casing without affecting the map beneath.",[14,1036,1037,1040,1041,1043],{},[162,1038,1039],{},"Why does my hillshade look grey rather than shaded?","\nThe thematic layer above it is opaque and using normal compositing. Set its blend mode to ",[192,1042,474],{},"; leave the hillshade itself fully opaque underneath.",[14,1045,1046,1049,1050,1054],{},[162,1047,1048],{},"Does opacity affect the legend?","\nNo. Legend patches are drawn at full strength, which is usually desirable but does surprise people producing a faded overlay. If the legend must match, ",[21,1051,1053],{"href":1052},"\u002Fspatial-data-processing-automation\u002Fautomated-map-layout-generation\u002Fadd-legend-to-layout-pyqgis\u002F","render the patch yourself"," or apply the alpha to the symbol colour rather than the layer.",[151,1056,1058],{"id":1057},"related","Related",[156,1060,1061,1066,1072,1077,1083],{},[159,1062,1063,1065],{},[21,1064,24],{"href":23}," — the guide this recipe belongs to",[159,1067,1068],{},[21,1069,1071],{"href":1070},"\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fcreate-heatmap-renderer-pyqgis\u002F","Build a Heatmap Renderer in PyQGIS",[159,1073,1074],{},[21,1075,1076],{"href":174},"Stack Symbol Layers in PyQGIS",[159,1078,1079],{},[21,1080,1082],{"href":1081},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fapply-color-ramp-to-raster-pyqgis\u002F","Apply a Color Ramp to a Raster in PyQGIS",[159,1084,1085],{},[21,1086,1088],{"href":1087},"\u002Fpyqgis-cartography-visualization\u002Fmap-canvas-and-image-export\u002Fexport-map-canvas-to-image-pyqgis\u002F","Export the Map Canvas to an Image in PyQGIS",[1090,1091,1092],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sjoCn, html code.shiki .sjoCn{--shiki-default:#9AA79F}",{"title":190,"searchDepth":215,"depth":215,"links":1094},[1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105],{"id":153,"depth":215,"text":154},{"id":179,"depth":215,"text":180},{"id":335,"depth":215,"text":336},{"id":416,"depth":215,"text":417},{"id":671,"depth":215,"text":672},{"id":770,"depth":215,"text":771},{"id":848,"depth":215,"text":849},{"id":949,"depth":215,"text":950},{"id":1003,"depth":215,"text":1004},{"id":1017,"depth":215,"text":1018},{"id":1057,"depth":215,"text":1058},"Control transparency and compositing from Python — layer opacity versus colour alpha, QPainter blend modes for shaded relief, feature blending, and the export caveat that rasterises your PDF.","md",{"slug":1109,"type":1110,"breadcrumb":1111,"datePublished":1112,"dateModified":1112},"set-layer-opacity-and-blend-mode-pyqgis","article","Opacity & Blend Modes","2026-08-27","\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fset-layer-opacity-and-blend-mode-pyqgis",{"title":5,"description":1106},"pyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fset-layer-opacity-and-blend-mode-pyqgis\u002Findex","g18Hd7Z4zz3Bw6N6ua4_8_z8bwU5yumv5etnm8iohko",1787823360561]