[{"data":1,"prerenderedAt":1733},["ShallowReactive",2],{"doc:\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis":3},{"id":4,"title":5,"body":6,"description":1722,"extension":1723,"meta":1724,"navigation":224,"path":1729,"seo":1730,"stem":1731,"__hash__":1732},"docs\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis\u002Findex.md","Add Diagram Legends and Text Diagrams in PyQGIS",{"type":7,"value":8,"toc":1707},"minimark",[9,13,17,26,159,164,184,188,191,304,334,338,341,466,480,554,558,561,725,739,743,746,810,1107,1112,1116,1119,1243,1248,1252,1255,1381,1391,1395,1398,1565,1574,1578,1600,1604,1632,1636,1643,1647,1653,1659,1665,1671,1675,1703],[10,11,5],"h1",{"id":12},"add-diagram-legends-and-text-diagrams-in-pyqgis",[14,15,16],"p",{},"A diagram without a legend is decoration. Readers need to know which colour is which category and, when diagrams are sized, what a given size means. QGIS can generate both from the diagram renderer: category entries for the colours and a size legend for the magnitudes, shown in the Layers panel and in print layout legends. And when a chart is overkill — when the reader simply needs the numbers — the text diagram prints values inside a circle, rectangle or triangle on each feature.",[14,18,19,20,25],{},"This recipe belongs to ",[21,22,24],"a",{"href":23},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002F","Diagrams & Charts on Maps",". It turns on category legends, builds size legends with sensible reference values, places diagram legends in print layouts, and configures text diagrams.",[14,27,28],{},[29,30,35,39,43,50,59,69,75,83,91,95,99,103,107,110,114,117,121,127,131,135,141,143,146,151,155],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 280","img","A diagram legend with category entries for colours and a size legend of nested reference circles with values","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"What a diagram legend contains",[40,41,42],"desc",{},"A diagram legend has two parts. Category entries list each colour with its label, generated from the diagram settings. A size legend shows reference diagrams for chosen values, either as separate items or collapsed into nested circles with leader lines. Both appear under the layer in the Layers panel and in print layout legends.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","280","#f6f3ea",[51,52,58],"text",{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"380","28","text-anchor:middle;font-size:14px;font-family:sans-serif;font-weight:bold","#17211d","middle","Colours, then sizes",[44,60],{"x":61,"y":62,"width":63,"height":64,"rx":65,"fill":66,"stroke":67,"style":68},"24","52","300","196","8","#fffdf7","#59645f","stroke-width:2",[51,70,74],{"x":71,"y":72,"style":73,"fill":56,"textAnchor":57},"174","153.78","text-anchor:middle;font-size:11.5px;font-family:sans-serif;font-weight:bold","category entries",[44,76],{"x":77,"y":78,"width":79,"height":80,"rx":46,"fill":81,"stroke":81,"style":82},"60","100","18","14","#2563eb","stroke-width:1.5",[51,84,90],{"x":85,"y":86,"style":87,"fill":88,"textAnchor":89},"90","112","text-anchor:start;font-size:10.5px;font-family:sans-serif","#2f3b35","start","party A",[44,92],{"x":77,"y":93,"width":79,"height":80,"rx":46,"fill":94,"stroke":94,"style":82},"130","#b91c1c",[51,96,98],{"x":85,"y":97,"style":87,"fill":88,"textAnchor":89},"142","party B",[44,100],{"x":77,"y":101,"width":79,"height":80,"rx":46,"fill":102,"stroke":102,"style":82},"160","#15803d",[51,104,106],{"x":85,"y":105,"style":87,"fill":88,"textAnchor":89},"172","party C",[44,108],{"x":77,"y":109,"width":79,"height":80,"rx":46,"fill":67,"stroke":67,"style":82},"190",[51,111,113],{"x":85,"y":112,"style":87,"fill":88,"textAnchor":89},"202","other",[44,115],{"x":116,"y":62,"width":53,"height":64,"rx":65,"fill":66,"stroke":67,"style":68},"356",[51,118,120],{"x":119,"y":72,"style":73,"fill":56,"textAnchor":57},"546","size legend (collapsed)",[122,123],"circle",{"cx":124,"cy":109,"r":125,"fill":126,"stroke":88,"style":82},"480","50","none",[122,128],{"cx":124,"cy":129,"r":130,"fill":126,"stroke":88,"style":82},"207","33",[122,132],{"cx":124,"cy":133,"r":134,"fill":126,"stroke":88,"style":82},"224","16",[136,137],"line",{"x1":124,"y1":138,"x2":139,"y2":138,"stroke":67,"style":140},"140","600","stroke-width:1",[136,142],{"x1":124,"y1":71,"x2":139,"y2":71,"stroke":67,"style":140},[136,144],{"x1":124,"y1":145,"x2":139,"y2":145,"stroke":67,"style":140},"208",[51,147,150],{"x":148,"y":149,"style":87,"fill":88,"textAnchor":89},"606","144","100,000",[51,152,154],{"x":148,"y":153,"style":87,"fill":88,"textAnchor":89},"178","50,000",[51,156,158],{"x":148,"y":157,"style":87,"fill":88,"textAnchor":89},"212","10,000",[160,161,163],"h2",{"id":162},"prerequisites","Prerequisites",[165,166,167,171],"ul",{},[168,169,170],"li",{},"QGIS 3.34 LTR or newer, or the QGIS 4 series.",[168,172,173,174,178,179,183],{},"A layer with a diagram renderer configured, as in ",[21,175,177],{"href":176},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-pie-chart-diagrams-pyqgis\u002F","adding pie chart diagrams"," or ",[21,180,182],{"href":181},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fsize-diagrams-by-attribute-pyqgis\u002F","sizing diagrams by attribute",".",[160,185,187],{"id":186},"turn-on-category-entries","Turn on category entries",[14,189,190],{},"Category entries come straight from the diagram settings: each category's colour and label. They are off by default.",[192,193,198],"pre",{"className":194,"code":195,"language":196,"meta":197,"style":197},"language-python shiki shiki-themes github-dark","from qgis.core import QgsProject\n\nconstituencies = QgsProject.instance().mapLayersByName(\"constituencies\")[0]\nrenderer = constituencies.diagramRenderer()\nrenderer.setAttributeLegend(True)\nconstituencies.setDiagramRenderer(renderer)\n\nfrom qgis.utils import iface\niface.layerTreeView().refreshLayerSymbology(constituencies.id())\n","python","",[199,200,201,219,226,251,262,274,280,285,298],"code",{"__ignoreMap":197},[202,203,205,209,213,216],"span",{"class":136,"line":204},1,[202,206,208],{"class":207},"snl16","from",[202,210,212],{"class":211},"s95oV"," qgis.core ",[202,214,215],{"class":207},"import",[202,217,218],{"class":211}," QgsProject\n",[202,220,222],{"class":136,"line":221},2,[202,223,225],{"emptyLinePlaceholder":224},true,"\n",[202,227,229,232,235,238,242,245,248],{"class":136,"line":228},3,[202,230,231],{"class":211},"constituencies ",[202,233,234],{"class":207},"=",[202,236,237],{"class":211}," QgsProject.instance().mapLayersByName(",[202,239,241],{"class":240},"sU2Wk","\"constituencies\"",[202,243,244],{"class":211},")[",[202,246,46],{"class":247},"sDLfK",[202,249,250],{"class":211},"]\n",[202,252,254,257,259],{"class":136,"line":253},4,[202,255,256],{"class":211},"renderer ",[202,258,234],{"class":207},[202,260,261],{"class":211}," constituencies.diagramRenderer()\n",[202,263,265,268,271],{"class":136,"line":264},5,[202,266,267],{"class":211},"renderer.setAttributeLegend(",[202,269,270],{"class":247},"True",[202,272,273],{"class":211},")\n",[202,275,277],{"class":136,"line":276},6,[202,278,279],{"class":211},"constituencies.setDiagramRenderer(renderer)\n",[202,281,283],{"class":136,"line":282},7,[202,284,225],{"emptyLinePlaceholder":224},[202,286,288,290,293,295],{"class":136,"line":287},8,[202,289,208],{"class":207},[202,291,292],{"class":211}," qgis.utils ",[202,294,215],{"class":207},[202,296,297],{"class":211}," iface\n",[202,299,301],{"class":136,"line":300},9,[202,302,303],{"class":211},"iface.layerTreeView().refreshLayerSymbology(constituencies.id())\n",[14,305,306,310,311,314,315,318,319,322,323,326,327,330,331,183],{},[307,308,309],"strong",{},"Breakdown:"," ",[199,312,313],{},"setAttributeLegend(True)"," adds one legend entry per category under the layer, using the colours and labels from ",[199,316,317],{},"QgsDiagramSettings",". Because the renderer returned by ",[199,320,321],{},"diagramRenderer()"," is owned by the layer, setting it back with ",[199,324,325],{},"setDiagramRenderer"," makes sure the layer notices the change; refreshing the layer tree view updates the Layers panel immediately. Labels come from ",[199,328,329],{},"categoryLabels",", so write them for readers — \"public transport\", not ",[199,332,333],{},"\"bus\" + \"tram\"",[160,335,337],{"id":336},"build-a-size-legend","Build a size legend",[14,339,340],{},"For sized diagrams, a size legend shows what particular sizes mean. Choosing round, representative values is the main decision.",[192,342,344],{"className":194,"code":343,"language":196,"meta":197,"style":197},"from qgis.core import QgsDataDefinedSizeLegend, QgsLinearlyInterpolatedDiagramRenderer\n\nif isinstance(renderer, QgsLinearlyInterpolatedDiagramRenderer):\n    legend = QgsDataDefinedSizeLegend()\n    legend.setTitle(\"votes cast\")\n    legend.setLegendType(QgsDataDefinedSizeLegend.LegendCollapsed)\n    legend.setClasses([\n        QgsDataDefinedSizeLegend.SizeClass(10000, \"10,000\"),\n        QgsDataDefinedSizeLegend.SizeClass(50000, \"50,000\"),\n        QgsDataDefinedSizeLegend.SizeClass(100000, \"100,000\"),\n    ])\n    renderer.setDataDefinedSizeLegend(legend)\n    constituencies.setDiagramRenderer(renderer)\n",[199,345,346,357,361,372,382,392,397,402,419,433,448,454,460],{"__ignoreMap":197},[202,347,348,350,352,354],{"class":136,"line":204},[202,349,208],{"class":207},[202,351,212],{"class":211},[202,353,215],{"class":207},[202,355,356],{"class":211}," QgsDataDefinedSizeLegend, QgsLinearlyInterpolatedDiagramRenderer\n",[202,358,359],{"class":136,"line":221},[202,360,225],{"emptyLinePlaceholder":224},[202,362,363,366,369],{"class":136,"line":228},[202,364,365],{"class":207},"if",[202,367,368],{"class":247}," isinstance",[202,370,371],{"class":211},"(renderer, QgsLinearlyInterpolatedDiagramRenderer):\n",[202,373,374,377,379],{"class":136,"line":253},[202,375,376],{"class":211},"    legend ",[202,378,234],{"class":207},[202,380,381],{"class":211}," QgsDataDefinedSizeLegend()\n",[202,383,384,387,390],{"class":136,"line":264},[202,385,386],{"class":211},"    legend.setTitle(",[202,388,389],{"class":240},"\"votes cast\"",[202,391,273],{"class":211},[202,393,394],{"class":136,"line":276},[202,395,396],{"class":211},"    legend.setLegendType(QgsDataDefinedSizeLegend.LegendCollapsed)\n",[202,398,399],{"class":136,"line":282},[202,400,401],{"class":211},"    legend.setClasses([\n",[202,403,404,407,410,413,416],{"class":136,"line":287},[202,405,406],{"class":211},"        QgsDataDefinedSizeLegend.SizeClass(",[202,408,409],{"class":247},"10000",[202,411,412],{"class":211},", ",[202,414,415],{"class":240},"\"10,000\"",[202,417,418],{"class":211},"),\n",[202,420,421,423,426,428,431],{"class":136,"line":300},[202,422,406],{"class":211},[202,424,425],{"class":247},"50000",[202,427,412],{"class":211},[202,429,430],{"class":240},"\"50,000\"",[202,432,418],{"class":211},[202,434,436,438,441,443,446],{"class":136,"line":435},10,[202,437,406],{"class":211},[202,439,440],{"class":247},"100000",[202,442,412],{"class":211},[202,444,445],{"class":240},"\"100,000\"",[202,447,418],{"class":211},[202,449,451],{"class":136,"line":450},11,[202,452,453],{"class":211},"    ])\n",[202,455,457],{"class":136,"line":456},12,[202,458,459],{"class":211},"    renderer.setDataDefinedSizeLegend(legend)\n",[202,461,463],{"class":136,"line":462},13,[202,464,465],{"class":211},"    constituencies.setDiagramRenderer(renderer)\n",[14,467,468,470,471,474,475,479],{},[307,469,309],{}," Explicit size classes with round values and formatted labels read far better than automatically chosen values such as 13,742. Pick values spanning the data: one near the typical feature, one near the largest, one small. Note that ",[199,472,473],{},"SizeClass"," takes the ",[476,477,478],"em",{},"value",", not the size; the renderer converts values to sizes with the same interpolation it uses on the map, so the legend is guaranteed to match. The collapsed type nests circles with leader lines, the compact convention for proportional symbols; the separated type lists each reference diagram as its own entry.",[14,481,482],{},[29,483,486,489,492,494,509,512,517,523,528,533,537,542,545,548],{"viewBox":484,"role":32,"ariaLabel":485,"xmlns":34},"0 0 760 212","Automatic legend values with awkward numbers compared with chosen round values that span the data",[36,487,488],{},"Choosing reference values",[40,490,491],{},"Automatic legend values come from the data range and produce awkward numbers such as 13,742 and 87,219. Chosen round values such as 10,000, 50,000 and 100,000 are easy to read and compare, and should span the data from a typical feature to the largest.",[44,493],{"x":46,"y":46,"width":47,"height":157,"fill":49},[495,496,497],"defs",{},[498,499,505],"marker",{"id":500,"viewBox":501,"refX":65,"refY":502,"markerWidth":503,"markerHeight":503,"orient":504},"legValuesArrow","0 0 10 10","5","7","auto-start-reverse",[506,507],"path",{"d":508,"fill":88},"M0 0 L10 5 L0 10 z",[51,510,511],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Round numbers that span the data",[44,513],{"x":61,"y":514,"width":515,"height":138,"rx":65,"fill":516,"stroke":94,"style":68},"56","340","#fdf2e2",[51,518,522],{"x":519,"y":520,"style":521,"fill":94,"textAnchor":57},"194","101.6","text-anchor:middle;font-size:11.0px;font-family:sans-serif;font-weight:bold","automatic",[51,524,527],{"x":519,"y":525,"style":526,"fill":88,"textAnchor":57},"129.6","text-anchor:middle;font-size:9.5px;font-family:monospace","13,742 · 47,903 · 87,219",[51,529,532],{"x":519,"y":530,"style":531,"fill":67,"textAnchor":57},"157.6","text-anchor:middle;font-size:10.0px;font-family:sans-serif","precise, unreadable",[44,534],{"x":535,"y":514,"width":515,"height":138,"rx":65,"fill":536,"stroke":102,"style":68},"396","#e8efe6",[51,538,541],{"x":539,"y":520,"style":521,"fill":540,"textAnchor":57},"566","#166534","chosen",[51,543,544],{"x":539,"y":525,"style":526,"fill":88,"textAnchor":57},"10,000 · 50,000 · 100,000",[51,546,547],{"x":539,"y":530,"style":531,"fill":67,"textAnchor":57},"round, comparable",[136,549],{"x1":550,"y1":551,"x2":552,"y2":551,"stroke":88,"style":553},"364","126","392","stroke-width:1.8;marker-end:url(#legValuesArrow)",[160,555,557],{"id":556},"put-the-legend-in-a-print-layout","Put the legend in a print layout",[14,559,560],{},"A layout legend item picks up diagram entries from the layer like any other symbology. With auto-update on, it follows changes; turning it off lets you reorder and rename entries.",[192,562,564],{"className":194,"code":563,"language":196,"meta":197,"style":197},"from qgis.core import (QgsLayoutItemLegend, QgsLayoutPoint, QgsLayoutSize,\n                       QgsUnitTypes, QgsLegendStyle)\n\nlayout = QgsProject.instance().layoutManager().layoutByName(\"Election map\")\nlegend_item = QgsLayoutItemLegend(layout)\nlegend_item.setTitle(\"\")\nmap_item = layout.itemById(\"main_map\")\nlegend_item.setLinkedMap(map_item)\nlegend_item.setAutoUpdateModel(False)\n\nmodel = legend_item.model()\nroot = model.rootGroup()\nroot.removeAllChildren()\nroot.addLayer(constituencies)\nlegend_item.updateLegend()\n\nlegend_item.attemptMove(QgsLayoutPoint(210, 140, QgsUnitTypes.LayoutMillimeters))\nlayout.addLayoutItem(legend_item)\nlegend_item.adjustBoxSize()\n",[199,565,566,577,582,586,601,611,621,636,641,651,655,665,675,680,686,692,697,713,719],{"__ignoreMap":197},[202,567,568,570,572,574],{"class":136,"line":204},[202,569,208],{"class":207},[202,571,212],{"class":211},[202,573,215],{"class":207},[202,575,576],{"class":211}," (QgsLayoutItemLegend, QgsLayoutPoint, QgsLayoutSize,\n",[202,578,579],{"class":136,"line":221},[202,580,581],{"class":211},"                       QgsUnitTypes, QgsLegendStyle)\n",[202,583,584],{"class":136,"line":228},[202,585,225],{"emptyLinePlaceholder":224},[202,587,588,591,593,596,599],{"class":136,"line":253},[202,589,590],{"class":211},"layout ",[202,592,234],{"class":207},[202,594,595],{"class":211}," QgsProject.instance().layoutManager().layoutByName(",[202,597,598],{"class":240},"\"Election map\"",[202,600,273],{"class":211},[202,602,603,606,608],{"class":136,"line":264},[202,604,605],{"class":211},"legend_item ",[202,607,234],{"class":207},[202,609,610],{"class":211}," QgsLayoutItemLegend(layout)\n",[202,612,613,616,619],{"class":136,"line":276},[202,614,615],{"class":211},"legend_item.setTitle(",[202,617,618],{"class":240},"\"\"",[202,620,273],{"class":211},[202,622,623,626,628,631,634],{"class":136,"line":282},[202,624,625],{"class":211},"map_item ",[202,627,234],{"class":207},[202,629,630],{"class":211}," layout.itemById(",[202,632,633],{"class":240},"\"main_map\"",[202,635,273],{"class":211},[202,637,638],{"class":136,"line":287},[202,639,640],{"class":211},"legend_item.setLinkedMap(map_item)\n",[202,642,643,646,649],{"class":136,"line":300},[202,644,645],{"class":211},"legend_item.setAutoUpdateModel(",[202,647,648],{"class":247},"False",[202,650,273],{"class":211},[202,652,653],{"class":136,"line":435},[202,654,225],{"emptyLinePlaceholder":224},[202,656,657,660,662],{"class":136,"line":450},[202,658,659],{"class":211},"model ",[202,661,234],{"class":207},[202,663,664],{"class":211}," legend_item.model()\n",[202,666,667,670,672],{"class":136,"line":456},[202,668,669],{"class":211},"root ",[202,671,234],{"class":207},[202,673,674],{"class":211}," model.rootGroup()\n",[202,676,677],{"class":136,"line":462},[202,678,679],{"class":211},"root.removeAllChildren()\n",[202,681,683],{"class":136,"line":682},14,[202,684,685],{"class":211},"root.addLayer(constituencies)\n",[202,687,689],{"class":136,"line":688},15,[202,690,691],{"class":211},"legend_item.updateLegend()\n",[202,693,695],{"class":136,"line":694},16,[202,696,225],{"emptyLinePlaceholder":224},[202,698,700,703,706,708,710],{"class":136,"line":699},17,[202,701,702],{"class":211},"legend_item.attemptMove(QgsLayoutPoint(",[202,704,705],{"class":247},"210",[202,707,412],{"class":211},[202,709,138],{"class":247},[202,711,712],{"class":211},", QgsUnitTypes.LayoutMillimeters))\n",[202,714,716],{"class":136,"line":715},18,[202,717,718],{"class":211},"layout.addLayoutItem(legend_item)\n",[202,720,722],{"class":136,"line":721},19,[202,723,724],{"class":211},"legend_item.adjustBoxSize()\n",[14,726,727,729,730,733,734,738],{},[307,728,309],{}," Linking the legend to the map item lets it filter to layers visible in that map. Turning off auto-update and rebuilding the root group with only the diagram layer produces a legend that shows exactly the diagram entries and nothing else — base layers and reference layers are usually better described in a caption. ",[199,731,732],{},"adjustBoxSize"," fits the frame to the content. ",[21,735,737],{"href":736},"\u002Fspatial-data-processing-automation\u002Fautomated-map-layout-generation\u002Fadd-legend-to-layout-pyqgis\u002F","Adding a legend to a layout"," covers styling, columns and filtering in depth.",[160,740,742],{"id":741},"print-values-with-a-text-diagram","Print values with a text diagram",[14,744,745],{},"Sometimes the numbers themselves are the message: turnout in each constituency, the count of incidents per district. A text diagram writes one or more values inside a simple shape on each feature, more compact than a label with a background and positioned by the diagram engine.",[14,747,748],{},[29,749,752,755,758,761,764,769,772,777,781,786,790,795,799,804,807],{"viewBox":750,"role":32,"ariaLabel":751,"xmlns":34},"0 0 760 226","Text diagrams with values inside a circle, a rectangle and a triangle, the circle split into two values",[36,753,754],{},"Text diagram shapes",[40,756,757],{},"A text diagram draws one to three values inside a circle, rectangle or triangle. With two categories, the shape is split by a line and each value sits in its own half, each optionally coloured by its category colour. Font and background colours follow the diagram settings.",[44,759],{"x":46,"y":46,"width":47,"height":760,"fill":49},"226",[51,762,763],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Values in a shape",[122,765],{"cx":766,"cy":767,"r":125,"fill":768,"stroke":81,"style":68},"150","120","#eff3ff",[136,770],{"x1":78,"y1":767,"x2":771,"y2":767,"stroke":81,"style":82},"200",[51,773,776],{"x":766,"y":774,"style":775,"fill":81,"textAnchor":57},"108","text-anchor:middle;font-size:12.0px;font-family:sans-serif;font-weight:bold","72 %",[51,778,780],{"x":766,"y":149,"style":779,"fill":88,"textAnchor":57},"text-anchor:middle;font-size:11.0px;font-family:sans-serif","41,200",[44,782],{"x":63,"y":783,"width":101,"height":784,"rx":785,"fill":536,"stroke":102,"style":68},"84","72","4",[51,787,789],{"x":53,"y":551,"style":788,"fill":540,"textAnchor":57},"text-anchor:middle;font-size:13.0px;font-family:sans-serif;font-weight:bold","1,284",[791,792],"polygon",{"points":793,"fill":516,"stroke":794,"style":68},"620,70 690,180 550,180","#b45309",[51,796,798],{"x":797,"y":101,"style":775,"fill":794,"textAnchor":57},"620","38",[51,800,803],{"x":766,"y":801,"style":802,"fill":67,"textAnchor":57},"206","text-anchor:middle;font-size:10.5px;font-family:sans-serif","circle, two values",[51,805,806],{"x":53,"y":801,"style":802,"fill":67,"textAnchor":57},"rectangle",[51,808,809],{"x":797,"y":801,"style":802,"fill":67,"textAnchor":57},"triangle",[192,811,813],{"className":194,"code":812,"language":196,"meta":197,"style":197},"from qgis.core import (QgsTextDiagram, QgsDiagramSettings,\n                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\nfrom qgis.PyQt.QtGui import QColor, QFont\nfrom qgis.PyQt.QtCore import QSizeF\n\nsettings = QgsDiagramSettings()\nsettings.categoryAttributes = [\"format_number(100 * \\\"votes_total\\\" \u002F \\\"electorate\\\", 0) || ' %'\",\n                               \"format_number(\\\"votes_total\\\", 0)\"]\nsettings.categoryColors = [QColor(\"#2563eb\"), QColor(\"#2f3b35\")]\nsettings.categoryLabels = [\"turnout\", \"votes cast\"]\nsettings.font = QFont(\"Noto Sans\", 8)\nsettings.backgroundColor = QColor(\"#eff3ff\")\nsettings.penColor = QColor(\"#2563eb\")\nsettings.penWidth = 0.3\nsettings.size = QSizeF(14, 14)\nsettings.enabled = True\n\ntext_diagram = QgsTextDiagram()\ntext_diagram.setShape(QgsTextDiagram.Circle)\ntext_renderer = QgsSingleCategoryDiagramRenderer()\ntext_renderer.setDiagram(text_diagram)\ntext_renderer.setDiagramSettings(settings)\nconstituencies.setDiagramRenderer(text_renderer)\nconstituencies.setDiagramLayerSettings(QgsDiagramLayerSettings())\nconstituencies.triggerRepaint()\n",[199,814,815,826,831,843,855,859,869,906,922,944,962,981,996,1009,1019,1037,1047,1051,1061,1066,1077,1083,1089,1095,1101],{"__ignoreMap":197},[202,816,817,819,821,823],{"class":136,"line":204},[202,818,208],{"class":207},[202,820,212],{"class":211},[202,822,215],{"class":207},[202,824,825],{"class":211}," (QgsTextDiagram, QgsDiagramSettings,\n",[202,827,828],{"class":136,"line":221},[202,829,830],{"class":211},"                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\n",[202,832,833,835,838,840],{"class":136,"line":228},[202,834,208],{"class":207},[202,836,837],{"class":211}," qgis.PyQt.QtGui ",[202,839,215],{"class":207},[202,841,842],{"class":211}," QColor, QFont\n",[202,844,845,847,850,852],{"class":136,"line":253},[202,846,208],{"class":207},[202,848,849],{"class":211}," qgis.PyQt.QtCore ",[202,851,215],{"class":207},[202,853,854],{"class":211}," QSizeF\n",[202,856,857],{"class":136,"line":264},[202,858,225],{"emptyLinePlaceholder":224},[202,860,861,864,866],{"class":136,"line":276},[202,862,863],{"class":211},"settings ",[202,865,234],{"class":207},[202,867,868],{"class":211}," QgsDiagramSettings()\n",[202,870,871,874,876,879,882,885,888,890,893,895,898,900,903],{"class":136,"line":282},[202,872,873],{"class":211},"settings.categoryAttributes ",[202,875,234],{"class":207},[202,877,878],{"class":211}," [",[202,880,881],{"class":240},"\"format_number(100 * ",[202,883,884],{"class":247},"\\\"",[202,886,887],{"class":240},"votes_total",[202,889,884],{"class":247},[202,891,892],{"class":240}," \u002F ",[202,894,884],{"class":247},[202,896,897],{"class":240},"electorate",[202,899,884],{"class":247},[202,901,902],{"class":240},", 0) || ' %'\"",[202,904,905],{"class":211},",\n",[202,907,908,911,913,915,917,920],{"class":136,"line":287},[202,909,910],{"class":240},"                               \"format_number(",[202,912,884],{"class":247},[202,914,887],{"class":240},[202,916,884],{"class":247},[202,918,919],{"class":240},", 0)\"",[202,921,250],{"class":211},[202,923,924,927,929,932,935,938,941],{"class":136,"line":300},[202,925,926],{"class":211},"settings.categoryColors ",[202,928,234],{"class":207},[202,930,931],{"class":211}," [QColor(",[202,933,934],{"class":240},"\"#2563eb\"",[202,936,937],{"class":211},"), QColor(",[202,939,940],{"class":240},"\"#2f3b35\"",[202,942,943],{"class":211},")]\n",[202,945,946,949,951,953,956,958,960],{"class":136,"line":435},[202,947,948],{"class":211},"settings.categoryLabels ",[202,950,234],{"class":207},[202,952,878],{"class":211},[202,954,955],{"class":240},"\"turnout\"",[202,957,412],{"class":211},[202,959,389],{"class":240},[202,961,250],{"class":211},[202,963,964,967,969,972,975,977,979],{"class":136,"line":450},[202,965,966],{"class":211},"settings.font ",[202,968,234],{"class":207},[202,970,971],{"class":211}," QFont(",[202,973,974],{"class":240},"\"Noto Sans\"",[202,976,412],{"class":211},[202,978,65],{"class":247},[202,980,273],{"class":211},[202,982,983,986,988,991,994],{"class":136,"line":456},[202,984,985],{"class":211},"settings.backgroundColor ",[202,987,234],{"class":207},[202,989,990],{"class":211}," QColor(",[202,992,993],{"class":240},"\"#eff3ff\"",[202,995,273],{"class":211},[202,997,998,1001,1003,1005,1007],{"class":136,"line":462},[202,999,1000],{"class":211},"settings.penColor ",[202,1002,234],{"class":207},[202,1004,990],{"class":211},[202,1006,934],{"class":240},[202,1008,273],{"class":211},[202,1010,1011,1014,1016],{"class":136,"line":682},[202,1012,1013],{"class":211},"settings.penWidth ",[202,1015,234],{"class":207},[202,1017,1018],{"class":247}," 0.3\n",[202,1020,1021,1024,1026,1029,1031,1033,1035],{"class":136,"line":688},[202,1022,1023],{"class":211},"settings.size ",[202,1025,234],{"class":207},[202,1027,1028],{"class":211}," QSizeF(",[202,1030,80],{"class":247},[202,1032,412],{"class":211},[202,1034,80],{"class":247},[202,1036,273],{"class":211},[202,1038,1039,1042,1044],{"class":136,"line":694},[202,1040,1041],{"class":211},"settings.enabled ",[202,1043,234],{"class":207},[202,1045,1046],{"class":247}," True\n",[202,1048,1049],{"class":136,"line":699},[202,1050,225],{"emptyLinePlaceholder":224},[202,1052,1053,1056,1058],{"class":136,"line":715},[202,1054,1055],{"class":211},"text_diagram ",[202,1057,234],{"class":207},[202,1059,1060],{"class":211}," QgsTextDiagram()\n",[202,1062,1063],{"class":136,"line":721},[202,1064,1065],{"class":211},"text_diagram.setShape(QgsTextDiagram.Circle)\n",[202,1067,1069,1072,1074],{"class":136,"line":1068},20,[202,1070,1071],{"class":211},"text_renderer ",[202,1073,234],{"class":207},[202,1075,1076],{"class":211}," QgsSingleCategoryDiagramRenderer()\n",[202,1078,1080],{"class":136,"line":1079},21,[202,1081,1082],{"class":211},"text_renderer.setDiagram(text_diagram)\n",[202,1084,1086],{"class":136,"line":1085},22,[202,1087,1088],{"class":211},"text_renderer.setDiagramSettings(settings)\n",[202,1090,1092],{"class":136,"line":1091},23,[202,1093,1094],{"class":211},"constituencies.setDiagramRenderer(text_renderer)\n",[202,1096,1098],{"class":136,"line":1097},24,[202,1099,1100],{"class":211},"constituencies.setDiagramLayerSettings(QgsDiagramLayerSettings())\n",[202,1102,1104],{"class":136,"line":1103},25,[202,1105,1106],{"class":211},"constituencies.triggerRepaint()\n",[14,1108,1109,1111],{},[307,1110,309],{}," For text diagrams, each category expression produces the text to show, so formatting — percentages, thousands separators, units — happens in the expression. Two categories split the shape into two halves, each with its own value; three split it into thirds. The font, background colour and outline come from the diagram settings. Text diagrams take part in the same collision handling as other diagrams, which is their advantage over labels with backgrounds when both charts and numbers share a map.",[160,1113,1115],{"id":1114},"keep-text-diagrams-readable","Keep text diagrams readable",[14,1117,1118],{},"Text diagrams are only useful if every value can be read at the printed size. Three settings decide it: the font size relative to the shape, the contrast between text and background, and how many diagrams are allowed to collide.",[192,1120,1122],{"className":194,"code":1121,"language":196,"meta":197,"style":197},"settings.font = QFont(\"Noto Sans\", 7)\nsettings.size = QSizeF(12, 12)\nsettings.backgroundColor = QColor(255, 255, 255, 230)    # nearly opaque white\nsettings.opacity = 1.0\ntext_renderer.setDiagramSettings(settings)\n\nls = QgsDiagramLayerSettings()\nls.setShowAllDiagrams(False)\nls.setPriority(7)\nconstituencies.setDiagramLayerSettings(ls)\nconstituencies.triggerRepaint()\n",[199,1123,1124,1140,1157,1188,1198,1202,1206,1216,1225,1234,1239],{"__ignoreMap":197},[202,1125,1126,1128,1130,1132,1134,1136,1138],{"class":136,"line":204},[202,1127,966],{"class":211},[202,1129,234],{"class":207},[202,1131,971],{"class":211},[202,1133,974],{"class":240},[202,1135,412],{"class":211},[202,1137,503],{"class":247},[202,1139,273],{"class":211},[202,1141,1142,1144,1146,1148,1151,1153,1155],{"class":136,"line":221},[202,1143,1023],{"class":211},[202,1145,234],{"class":207},[202,1147,1028],{"class":211},[202,1149,1150],{"class":247},"12",[202,1152,412],{"class":211},[202,1154,1150],{"class":247},[202,1156,273],{"class":211},[202,1158,1159,1161,1163,1165,1168,1170,1172,1174,1176,1178,1181,1184],{"class":136,"line":228},[202,1160,985],{"class":211},[202,1162,234],{"class":207},[202,1164,990],{"class":211},[202,1166,1167],{"class":247},"255",[202,1169,412],{"class":211},[202,1171,1167],{"class":247},[202,1173,412],{"class":211},[202,1175,1167],{"class":247},[202,1177,412],{"class":211},[202,1179,1180],{"class":247},"230",[202,1182,1183],{"class":211},")    ",[202,1185,1187],{"class":1186},"sjoCn","# nearly opaque white\n",[202,1189,1190,1193,1195],{"class":136,"line":253},[202,1191,1192],{"class":211},"settings.opacity ",[202,1194,234],{"class":207},[202,1196,1197],{"class":247}," 1.0\n",[202,1199,1200],{"class":136,"line":264},[202,1201,1088],{"class":211},[202,1203,1204],{"class":136,"line":276},[202,1205,225],{"emptyLinePlaceholder":224},[202,1207,1208,1211,1213],{"class":136,"line":282},[202,1209,1210],{"class":211},"ls ",[202,1212,234],{"class":207},[202,1214,1215],{"class":211}," QgsDiagramLayerSettings()\n",[202,1217,1218,1221,1223],{"class":136,"line":287},[202,1219,1220],{"class":211},"ls.setShowAllDiagrams(",[202,1222,648],{"class":247},[202,1224,273],{"class":211},[202,1226,1227,1230,1232],{"class":136,"line":300},[202,1228,1229],{"class":211},"ls.setPriority(",[202,1231,503],{"class":247},[202,1233,273],{"class":211},[202,1235,1236],{"class":136,"line":435},[202,1237,1238],{"class":211},"constituencies.setDiagramLayerSettings(ls)\n",[202,1240,1241],{"class":136,"line":450},[202,1242,1106],{"class":211},[14,1244,1245,1247],{},[307,1246,309],{}," A font around 7 pt in a 12 mm shape leaves room for a five-digit number and a percentage on two lines; check the longest value you expect, not the typical one. An almost opaque white background guarantees contrast whatever the map colour underneath is, which matters more for numbers than for chart colours. Disallowing overlaps hides some values when the map is crowded; raising the priority of the text diagram layer above other labels makes the numbers win the space when they are the point of the map. When too many values disappear, a table beside the map, generated from the same layer, is often the better design.",[160,1249,1251],{"id":1250},"save-the-setup-as-a-style","Save the setup as a style",[14,1253,1254],{},"Legends, size classes, captions-to-be and text diagram settings take effort to get right. Saving the layer's style captures the diagram renderer, its legend settings and the layer settings in one QML file, so the next map — or next year's map — starts from the finished design.",[192,1256,1258],{"className":194,"code":1257,"language":196,"meta":197,"style":197},"from qgis.core import QgsMapLayer\n\nok, msg = constituencies.saveNamedStyle(\n    \"\u002Fdata\u002Fstyles\u002Fconstituency_diagrams.qml\",\n    categories=QgsMapLayer.Diagrams | QgsMapLayer.Symbology | QgsMapLayer.Labeling)\nprint(ok, msg)\n\n# later, on another layer with the same fields\nother = QgsProject.instance().mapLayersByName(\"constituencies_2030\")[0]\nother.loadNamedStyle(\"\u002Fdata\u002Fstyles\u002Fconstituency_diagrams.qml\",\n                     categories=QgsMapLayer.Diagrams | QgsMapLayer.Symbology | QgsMapLayer.Labeling)\nother.triggerRepaint()\n",[199,1259,1260,1271,1275,1285,1292,1314,1322,1326,1331,1349,1359,1376],{"__ignoreMap":197},[202,1261,1262,1264,1266,1268],{"class":136,"line":204},[202,1263,208],{"class":207},[202,1265,212],{"class":211},[202,1267,215],{"class":207},[202,1269,1270],{"class":211}," QgsMapLayer\n",[202,1272,1273],{"class":136,"line":221},[202,1274,225],{"emptyLinePlaceholder":224},[202,1276,1277,1280,1282],{"class":136,"line":228},[202,1278,1279],{"class":211},"ok, msg ",[202,1281,234],{"class":207},[202,1283,1284],{"class":211}," constituencies.saveNamedStyle(\n",[202,1286,1287,1290],{"class":136,"line":253},[202,1288,1289],{"class":240},"    \"\u002Fdata\u002Fstyles\u002Fconstituency_diagrams.qml\"",[202,1291,905],{"class":211},[202,1293,1294,1298,1300,1303,1306,1309,1311],{"class":136,"line":264},[202,1295,1297],{"class":1296},"s9osk","    categories",[202,1299,234],{"class":207},[202,1301,1302],{"class":211},"QgsMapLayer.Diagrams ",[202,1304,1305],{"class":207},"|",[202,1307,1308],{"class":211}," QgsMapLayer.Symbology ",[202,1310,1305],{"class":207},[202,1312,1313],{"class":211}," QgsMapLayer.Labeling)\n",[202,1315,1316,1319],{"class":136,"line":276},[202,1317,1318],{"class":247},"print",[202,1320,1321],{"class":211},"(ok, msg)\n",[202,1323,1324],{"class":136,"line":282},[202,1325,225],{"emptyLinePlaceholder":224},[202,1327,1328],{"class":136,"line":287},[202,1329,1330],{"class":1186},"# later, on another layer with the same fields\n",[202,1332,1333,1336,1338,1340,1343,1345,1347],{"class":136,"line":300},[202,1334,1335],{"class":211},"other ",[202,1337,234],{"class":207},[202,1339,237],{"class":211},[202,1341,1342],{"class":240},"\"constituencies_2030\"",[202,1344,244],{"class":211},[202,1346,46],{"class":247},[202,1348,250],{"class":211},[202,1350,1351,1354,1357],{"class":136,"line":435},[202,1352,1353],{"class":211},"other.loadNamedStyle(",[202,1355,1356],{"class":240},"\"\u002Fdata\u002Fstyles\u002Fconstituency_diagrams.qml\"",[202,1358,905],{"class":211},[202,1360,1361,1364,1366,1368,1370,1372,1374],{"class":136,"line":450},[202,1362,1363],{"class":1296},"                     categories",[202,1365,234],{"class":207},[202,1367,1302],{"class":211},[202,1369,1305],{"class":207},[202,1371,1308],{"class":211},[202,1373,1305],{"class":207},[202,1375,1313],{"class":211},[202,1377,1378],{"class":136,"line":456},[202,1379,1380],{"class":211},"other.triggerRepaint()\n",[14,1382,1383,1385,1386,1390],{},[307,1384,309],{}," Restricting the saved categories to diagrams, symbology and labelling keeps unrelated properties — field aliases, forms, actions — out of the style, so it can be applied to any layer with the same field names. Size legend classes are stored with the diagram renderer, so the round reference values come along. Remember that an upper value saved in the style is a fixed number; if next year's data exceeds it, recompute it after loading. ",[21,1387,1389],{"href":1388},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002Fsave-and-load-qml-style-pyqgis\u002F","Saving and loading QML styles"," covers style categories in general.",[160,1392,1394],{"id":1393},"explain-diagrams-in-the-caption","Explain diagrams in the caption",[14,1396,1397],{},"Even a complete legend benefits from a sentence of explanation, especially for sized diagrams. A layout label generated from the same values the renderer uses keeps the caption correct after data updates.",[192,1399,1401],{"className":194,"code":1400,"language":196,"meta":197,"style":197},"from qgis.core import QgsLayoutItemLabel\n\nupper = renderer.upperValue() if hasattr(renderer, \"upperValue\") else None\ncaption = QgsLayoutItemLabel(layout)\ncaption.setText(\n    \"Pie area is proportional to votes cast\"\n    + (f\"; the largest pie represents {upper:,.0f} votes.\" if upper else \".\")\n    + \" Slices show each party's share.\")\ncaption.setFont(QFont(\"Noto Sans\", 7))\ncaption.attemptMove(QgsLayoutPoint(210, 190, QgsUnitTypes.LayoutMillimeters))\ncaption.attemptResize(QgsLayoutSize(80, 14, QgsUnitTypes.LayoutMillimeters))\nlayout.addLayoutItem(caption)\n",[199,1402,1403,1414,1418,1448,1458,1463,1468,1510,1519,1533,1546,1560],{"__ignoreMap":197},[202,1404,1405,1407,1409,1411],{"class":136,"line":204},[202,1406,208],{"class":207},[202,1408,212],{"class":211},[202,1410,215],{"class":207},[202,1412,1413],{"class":211}," QgsLayoutItemLabel\n",[202,1415,1416],{"class":136,"line":221},[202,1417,225],{"emptyLinePlaceholder":224},[202,1419,1420,1423,1425,1428,1430,1433,1436,1439,1442,1445],{"class":136,"line":228},[202,1421,1422],{"class":211},"upper ",[202,1424,234],{"class":207},[202,1426,1427],{"class":211}," renderer.upperValue() ",[202,1429,365],{"class":207},[202,1431,1432],{"class":247}," hasattr",[202,1434,1435],{"class":211},"(renderer, ",[202,1437,1438],{"class":240},"\"upperValue\"",[202,1440,1441],{"class":211},") ",[202,1443,1444],{"class":207},"else",[202,1446,1447],{"class":247}," None\n",[202,1449,1450,1453,1455],{"class":136,"line":253},[202,1451,1452],{"class":211},"caption ",[202,1454,234],{"class":207},[202,1456,1457],{"class":211}," QgsLayoutItemLabel(layout)\n",[202,1459,1460],{"class":136,"line":264},[202,1461,1462],{"class":211},"caption.setText(\n",[202,1464,1465],{"class":136,"line":276},[202,1466,1467],{"class":240},"    \"Pie area is proportional to votes cast\"\n",[202,1469,1470,1473,1476,1479,1482,1485,1488,1491,1494,1497,1500,1503,1505,1508],{"class":136,"line":282},[202,1471,1472],{"class":207},"    +",[202,1474,1475],{"class":211}," (",[202,1477,1478],{"class":207},"f",[202,1480,1481],{"class":240},"\"; the largest pie represents ",[202,1483,1484],{"class":247},"{",[202,1486,1487],{"class":211},"upper",[202,1489,1490],{"class":207},":,.0f",[202,1492,1493],{"class":247},"}",[202,1495,1496],{"class":240}," votes.\"",[202,1498,1499],{"class":207}," if",[202,1501,1502],{"class":211}," upper ",[202,1504,1444],{"class":207},[202,1506,1507],{"class":240}," \".\"",[202,1509,273],{"class":211},[202,1511,1512,1514,1517],{"class":136,"line":287},[202,1513,1472],{"class":207},[202,1515,1516],{"class":240}," \" Slices show each party's share.\"",[202,1518,273],{"class":211},[202,1520,1521,1524,1526,1528,1530],{"class":136,"line":300},[202,1522,1523],{"class":211},"caption.setFont(QFont(",[202,1525,974],{"class":240},[202,1527,412],{"class":211},[202,1529,503],{"class":247},[202,1531,1532],{"class":211},"))\n",[202,1534,1535,1538,1540,1542,1544],{"class":136,"line":435},[202,1536,1537],{"class":211},"caption.attemptMove(QgsLayoutPoint(",[202,1539,705],{"class":247},[202,1541,412],{"class":211},[202,1543,109],{"class":247},[202,1545,712],{"class":211},[202,1547,1548,1551,1554,1556,1558],{"class":136,"line":450},[202,1549,1550],{"class":211},"caption.attemptResize(QgsLayoutSize(",[202,1552,1553],{"class":247},"80",[202,1555,412],{"class":211},[202,1557,80],{"class":247},[202,1559,712],{"class":211},[202,1561,1562],{"class":136,"line":456},[202,1563,1564],{"class":211},"layout.addLayoutItem(caption)\n",[14,1566,1567,1569,1570,1573],{},[307,1568,309],{}," Reading the upper value from the renderer means the caption always states the scale actually used, even if the script recomputes it for new data. Saying explicitly that ",[476,1571,1572],{},"area"," is proportional prevents readers from comparing diameters. Captions like this are cheap and remove most of the misreadings that diagram maps invite.",[160,1575,1577],{"id":1576},"qgis-version-compatibility","QGIS version compatibility",[14,1579,1580,1581,1584,1585,1588,1589,1592,1593,1596,1597,183],{},"Attribute legends, size legends for diagrams and text diagrams work on QGIS 3.34 LTR, 3.40 LTR and QGIS 4. ",[199,1582,1583],{},"QgsDataDefinedSizeLegend.SizeClass"," and the collapsed legend type exist since 3.4. On QGIS 4, enums are scoped, for example ",[199,1586,1587],{},"QgsTextDiagram.Shape.Circle"," and ",[199,1590,1591],{},"QgsDataDefinedSizeLegend.LegendType.LegendCollapsed","; ",[199,1594,1595],{},"QgsUnitTypes.LayoutMillimeters"," becomes ",[199,1598,1599],{},"Qgis.LayoutUnit.Millimeters",[160,1601,1603],{"id":1602},"troubleshooting","Troubleshooting",[165,1605,1606,1614,1620,1626],{},[168,1607,1608,310,1611,1613],{},[307,1609,1610],{},"No diagram entries in the legend.",[199,1612,313],{}," was not set, or the renderer was not reassigned to the layer.",[168,1615,1616,1619],{},[307,1617,1618],{},"Size legend values look odd."," They were chosen automatically; set explicit size classes.",[168,1621,1622,1625],{},[307,1623,1624],{},"Text diagrams show expressions instead of values."," A field name was used without quotes or the expression has a syntax error; test it in the expression builder.",[168,1627,1628,1631],{},[307,1629,1630],{},"The layout legend lists every layer."," Auto-update is on; turn it off and rebuild the root group.",[160,1633,1635],{"id":1634},"conclusion","Conclusion",[14,1637,1638,1639,1642],{},"Turn on category entries with ",[199,1640,1641],{},"setAttributeLegend",", build size legends with explicit round reference values that span the data, add a layout legend that shows only the diagram layer, use text diagrams when the numbers themselves matter, and add a caption that states what size means.",[160,1644,1646],{"id":1645},"frequently-asked-questions","Frequently Asked Questions",[14,1648,1649,1652],{},[307,1650,1651],{},"Can the size legend show bars?","\nThe collapsed style is designed for circles; for bars, state the scale in a caption or draw a reference bar.",[14,1654,1655,1658],{},[307,1656,1657],{},"Can text diagrams show three values?","\nYes; with three categories the shape is divided into three parts.",[14,1660,1661,1664],{},[307,1662,1663],{},"Do diagram legends work in the QGIS Server legend?","\nYes; GetLegendGraphic includes diagram entries when the attribute legend is enabled.",[14,1666,1667,1670],{},[307,1668,1669],{},"Can I style legend text separately from map labels?","\nYes, through the legend item's text formats in the layout.",[160,1672,1674],{"id":1673},"related","Related",[165,1676,1677,1682,1687,1692,1697],{},[168,1678,1679,1681],{},[21,1680,24],{"href":23}," — the guide this recipe belongs to",[168,1683,1684],{},[21,1685,1686],{"href":181},"Size Diagrams by Attribute in PyQGIS",[168,1688,1689],{},[21,1690,1691],{"href":176},"Add Pie Chart Diagrams to a Layer in PyQGIS",[168,1693,1694],{},[21,1695,1696],{"href":736},"Add a Legend to a Print Layout in PyQGIS",[168,1698,1699],{},[21,1700,1702],{"href":1701},"\u002Fspatial-data-processing-automation\u002Fautomated-map-layout-generation\u002Fadd-label-and-html-items-to-layout-pyqgis\u002F","Add Label and HTML Items to a Layout in PyQGIS",[1704,1705,1706],"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}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":197,"searchDepth":221,"depth":221,"links":1708},[1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721],{"id":162,"depth":221,"text":163},{"id":186,"depth":221,"text":187},{"id":336,"depth":221,"text":337},{"id":556,"depth":221,"text":557},{"id":741,"depth":221,"text":742},{"id":1114,"depth":221,"text":1115},{"id":1250,"depth":221,"text":1251},{"id":1393,"depth":221,"text":1394},{"id":1576,"depth":221,"text":1577},{"id":1602,"depth":221,"text":1603},{"id":1634,"depth":221,"text":1635},{"id":1645,"depth":221,"text":1646},{"id":1673,"depth":221,"text":1674},"Make diagrams readable with legends — category entries, size legends with chosen reference values, legends in print layouts — and use text diagrams to print values in a shape on each feature, with formatting, background and placement that hold up in print.","md",{"slug":1725,"type":1726,"breadcrumb":1727,"datePublished":1728,"dateModified":1728},"add-diagram-legend-and-text-diagrams-pyqgis","article","Diagram Legends and Text Diagrams","2026-10-02","\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis",{"title":5,"description":1722},"pyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis\u002Findex","b7AsAwYDk51LfH1dGMkDdASeu_MlDoGfbEQvdFBaCtA",1790966252898]