[{"data":1,"prerenderedAt":1552},["ShallowReactive",2],{"doc:\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps":3},{"id":4,"title":5,"body":6,"description":1541,"extension":1542,"meta":1543,"navigation":339,"path":1548,"seo":1549,"stem":1550,"__hash__":1551},"docs\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Findex.md","Diagrams & Charts on Maps with PyQGIS",{"type":7,"value":8,"toc":1523},"minimark",[9,13,17,26,156,161,207,211,214,241,251,265,274,534,549,553,556,562,568,574,580,583,587,590,665,676,680,683,777,782,786,793,797,800,854,866,870,873,879,885,891,897,903,970,975,979,992,996,1009,1013,1021,1025,1071,1075,1078,1377,1382,1386,1412,1416,1422,1432,1438,1444,1450,1454,1519],[10,11,5],"h1",{"id":12},"diagrams-charts-on-maps-with-pyqgis",[14,15,16],"p",{},"Most thematic maps show one value per feature: a colour for population density, a symbol size for the number of jobs. Many questions need more than one value at once. What is the mix of transport modes in each district? How do votes split between parties in each constituency, and how many were cast? How has a station's rainfall varied across the year? Answering them on a map means drawing a small chart at every feature — a diagram — or placing a full chart beside the map in a layout.",[14,18,19,20,25],{},"This guide belongs to ",[21,22,24],"a",{"href":23},"\u002Fpyqgis-cartography-visualization\u002F","PyQGIS Cartography & Data Visualization",". It is for anyone producing thematic maps from Python who needs to show composition, comparison or change alongside location: analysts writing reports, cartographers automating map series, and developers building map-producing tools. It explains how QGIS's diagram system is put together, which diagram fits which question, how to size diagrams honestly, and how to add proper charts to print layouts.",[14,27,28],{},[29,30,35,39,43,50,59,69,75,81,85,90,95,99,102,105,108,113,117,120,123,126,132,136,139,142,145,152],"svg",{"viewBox":31,"role":32,"ariaLabel":33,"xmlns":34},"0 0 760 320","img","Four diagram types — pie, bars, stacked bar and text — matched to the messages they convey best, with sizing and layout charts as complements","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[36,37,38],"title",{},"Which diagram for which message",[40,41,42],"desc",{},"Four diagram types and the message each conveys best. Pie: parts of a whole, two to five categories, rough comparison. Histogram bars: comparing the same category across features or categories with each other in absolute terms. Stacked bar: a total and its composition together. Text diagram: the numbers themselves. Each can be sized by an attribute to add magnitude, and full charts in a layout complement them when detail is needed.",[44,45],"rect",{"x":46,"y":46,"width":47,"height":48,"fill":49},"0","760","320","#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","Match the diagram to the message",[44,60],{"x":61,"y":62,"width":63,"height":64,"rx":65,"fill":66,"stroke":67,"style":68},"24","52","168","200","8","#eef7f4","#0f766e","stroke-width:2",[51,70,74],{"x":71,"y":72,"style":73,"fill":67,"textAnchor":57},"108","113.78","text-anchor:middle;font-size:11.5px;font-family:sans-serif;font-weight:bold","pie",[51,76,80],{"x":71,"y":77,"style":78,"fill":79,"textAnchor":57},"141.78","text-anchor:middle;font-size:10.5px;font-family:sans-serif","#2f3b35","parts of",[51,82,84],{"x":71,"y":83,"style":78,"fill":79,"textAnchor":57},"169.78","a whole",[51,86,89],{"x":71,"y":87,"style":78,"fill":88,"textAnchor":57},"197.78","#59645f","2–5 slices",[44,91],{"x":92,"y":62,"width":63,"height":64,"rx":65,"fill":93,"stroke":94,"style":68},"206","#eff3ff","#2563eb",[51,96,98],{"x":97,"y":72,"style":73,"fill":94,"textAnchor":57},"290","histogram",[51,100,101],{"x":97,"y":77,"style":78,"fill":79,"textAnchor":57},"compare",[51,103,104],{"x":97,"y":83,"style":78,"fill":79,"textAnchor":57},"values",[51,106,107],{"x":97,"y":87,"style":78,"fill":88,"textAnchor":57},"shared scale",[44,109],{"x":110,"y":62,"width":63,"height":64,"rx":65,"fill":111,"stroke":112,"style":68},"388","#fdf2e2","#b45309",[51,114,116],{"x":115,"y":72,"style":73,"fill":112,"textAnchor":57},"472","stacked bar",[51,118,119],{"x":115,"y":77,"style":78,"fill":79,"textAnchor":57},"total and",[51,121,122],{"x":115,"y":83,"style":78,"fill":79,"textAnchor":57},"composition",[51,124,125],{"x":115,"y":87,"style":78,"fill":88,"textAnchor":57},"focus first",[44,127],{"x":128,"y":62,"width":129,"height":64,"rx":65,"fill":130,"stroke":131,"style":68},"570","166","#e8efe6","#15803d",[51,133,51],{"x":134,"y":72,"style":73,"fill":135,"textAnchor":57},"653","#166534",[51,137,138],{"x":134,"y":77,"style":78,"fill":79,"textAnchor":57},"the numbers",[51,140,141],{"x":134,"y":83,"style":78,"fill":79,"textAnchor":57},"themselves",[51,143,144],{"x":134,"y":87,"style":78,"fill":88,"textAnchor":57},"format in expr",[44,146],{"x":147,"y":148,"width":149,"height":150,"rx":65,"fill":151,"stroke":88,"style":68},"140","270","480","40","#fffdf7",[51,153,155],{"x":53,"y":154,"style":78,"fill":79,"textAnchor":57},"293.78","size by attribute for magnitude · chart in layout for detail",[157,158,160],"h2",{"id":159},"what-this-guide-covers","What this guide covers",[162,163,164,172,179,186,193,200],"ul",{},[165,166,167,171],"li",{},[21,168,170],{"href":169},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-pie-chart-diagrams-pyqgis\u002F","Add pie chart diagrams to a layer"," for parts of a whole, with grouped categories, matching colours and clean placement.",[165,173,174,178],{},[21,175,177],{"href":176},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-histogram-bar-diagrams-pyqgis\u002F","Add histogram bar diagrams"," on one shared scale so bars compare across the map.",[165,180,181,185],{},[21,182,184],{"href":183},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-stacked-bar-diagrams-pyqgis\u002F","Add stacked bar diagrams"," to show totals and composition together, and combine diagrams per feature.",[165,187,188,192],{},[21,189,191],{"href":190},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fsize-diagrams-by-attribute-pyqgis\u002F","Size diagrams by attribute"," with area scaling, outlier handling and one scale across a series.",[165,194,195,199],{},[21,196,198],{"href":197},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-diagram-legend-and-text-diagrams-pyqgis\u002F","Add diagram legends and text diagrams"," so readers can decode colours and sizes, or read values directly.",[165,201,202,206],{},[21,203,205],{"href":204},"\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Fadd-chart-to-print-layout-pyqgis\u002F","Add a chart to a print layout"," with matplotlib, per atlas page, or with the native chart item.",[157,208,210],{"id":209},"how-the-diagram-system-fits-together","How the diagram system fits together",[14,212,213],{},"Diagrams are a property of a vector layer, separate from its symbology and labels. Four objects configure them, and every recipe in this guide uses the same four.",[14,215,216,217,221,222,226,227,226,230,226,233,236,237,240],{},"The ",[218,219,220],"strong",{},"diagram type"," — ",[223,224,225],"code",{},"QgsPieDiagram",", ",[223,228,229],{},"QgsHistogramDiagram",[223,231,232],{},"QgsStackedBarDiagram",[223,234,235],{},"QgsTextDiagram",", and on QGIS 3.40 and newer the container ",[223,238,239],{},"QgsStackedDiagram"," — decides how values are drawn.",[14,242,216,243,246,247,250],{},[218,244,245],{},"diagram settings"," (",[223,248,249],{},"QgsDiagramSettings",") hold the categories, which are expressions, along with their colours and labels, plus size, outline, font, background, orientation and visibility scales.",[14,252,216,253,256,257,260,261,264],{},[218,254,255],{},"diagram renderer"," combines type and settings and decides size. ",[223,258,259],{},"QgsSingleCategoryDiagramRenderer"," draws every diagram at the same size; ",[223,262,263],{},"QgsLinearlyInterpolatedDiagramRenderer"," maps a value — a field or expression — to a size range.",[14,266,216,267,246,270,273],{},[218,268,269],{},"diagram layer settings",[223,271,272],{},"QgsDiagramLayerSettings",") decide placement, priority, z-order and whether colliding diagrams are hidden, through the same labelling engine that places labels.",[275,276,281],"pre",{"className":277,"code":278,"language":279,"meta":280,"style":280},"language-python shiki shiki-themes github-dark","from qgis.core import (QgsProject, QgsPieDiagram, QgsDiagramSettings,\n                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\nfrom qgis.PyQt.QtGui import QColor\nfrom qgis.PyQt.QtCore import QSizeF\n\nlayer = QgsProject.instance().mapLayersByName(\"districts\")[0]\ns = QgsDiagramSettings()\ns.categoryAttributes = ['\"walk\" + \"cycle\"', '\"bus\" + \"rail\"', '\"car\"']\ns.categoryColors = [QColor(\"#15803d\"), QColor(\"#2563eb\"), QColor(\"#b45309\")]\ns.categoryLabels = [\"active\", \"public transport\", \"car\"]\ns.size = QSizeF(10, 10)\ns.enabled = True\n\nr = QgsSingleCategoryDiagramRenderer()\nr.setDiagram(QgsPieDiagram())\nr.setDiagramSettings(s)\nlayer.setDiagramRenderer(r)\nlayer.setDiagramLayerSettings(QgsDiagramLayerSettings())\nlayer.triggerRepaint()\n","python","",[223,282,283,302,308,321,334,341,366,377,403,431,456,477,488,493,504,510,516,522,528],{"__ignoreMap":280},[284,285,288,292,296,299],"span",{"class":286,"line":287},"line",1,[284,289,291],{"class":290},"snl16","from",[284,293,295],{"class":294},"s95oV"," qgis.core ",[284,297,298],{"class":290},"import",[284,300,301],{"class":294}," (QgsProject, QgsPieDiagram, QgsDiagramSettings,\n",[284,303,305],{"class":286,"line":304},2,[284,306,307],{"class":294},"                       QgsSingleCategoryDiagramRenderer, QgsDiagramLayerSettings)\n",[284,309,311,313,316,318],{"class":286,"line":310},3,[284,312,291],{"class":290},[284,314,315],{"class":294}," qgis.PyQt.QtGui ",[284,317,298],{"class":290},[284,319,320],{"class":294}," QColor\n",[284,322,324,326,329,331],{"class":286,"line":323},4,[284,325,291],{"class":290},[284,327,328],{"class":294}," qgis.PyQt.QtCore ",[284,330,298],{"class":290},[284,332,333],{"class":294}," QSizeF\n",[284,335,337],{"class":286,"line":336},5,[284,338,340],{"emptyLinePlaceholder":339},true,"\n",[284,342,344,347,350,353,357,360,363],{"class":286,"line":343},6,[284,345,346],{"class":294},"layer ",[284,348,349],{"class":290},"=",[284,351,352],{"class":294}," QgsProject.instance().mapLayersByName(",[284,354,356],{"class":355},"sU2Wk","\"districts\"",[284,358,359],{"class":294},")[",[284,361,46],{"class":362},"sDLfK",[284,364,365],{"class":294},"]\n",[284,367,369,372,374],{"class":286,"line":368},7,[284,370,371],{"class":294},"s ",[284,373,349],{"class":290},[284,375,376],{"class":294}," QgsDiagramSettings()\n",[284,378,380,383,385,388,391,393,396,398,401],{"class":286,"line":379},8,[284,381,382],{"class":294},"s.categoryAttributes ",[284,384,349],{"class":290},[284,386,387],{"class":294}," [",[284,389,390],{"class":355},"'\"walk\" + \"cycle\"'",[284,392,226],{"class":294},[284,394,395],{"class":355},"'\"bus\" + \"rail\"'",[284,397,226],{"class":294},[284,399,400],{"class":355},"'\"car\"'",[284,402,365],{"class":294},[284,404,406,409,411,414,417,420,423,425,428],{"class":286,"line":405},9,[284,407,408],{"class":294},"s.categoryColors ",[284,410,349],{"class":290},[284,412,413],{"class":294}," [QColor(",[284,415,416],{"class":355},"\"#15803d\"",[284,418,419],{"class":294},"), QColor(",[284,421,422],{"class":355},"\"#2563eb\"",[284,424,419],{"class":294},[284,426,427],{"class":355},"\"#b45309\"",[284,429,430],{"class":294},")]\n",[284,432,434,437,439,441,444,446,449,451,454],{"class":286,"line":433},10,[284,435,436],{"class":294},"s.categoryLabels ",[284,438,349],{"class":290},[284,440,387],{"class":294},[284,442,443],{"class":355},"\"active\"",[284,445,226],{"class":294},[284,447,448],{"class":355},"\"public transport\"",[284,450,226],{"class":294},[284,452,453],{"class":355},"\"car\"",[284,455,365],{"class":294},[284,457,459,462,464,467,470,472,474],{"class":286,"line":458},11,[284,460,461],{"class":294},"s.size ",[284,463,349],{"class":290},[284,465,466],{"class":294}," QSizeF(",[284,468,469],{"class":362},"10",[284,471,226],{"class":294},[284,473,469],{"class":362},[284,475,476],{"class":294},")\n",[284,478,480,483,485],{"class":286,"line":479},12,[284,481,482],{"class":294},"s.enabled ",[284,484,349],{"class":290},[284,486,487],{"class":362}," True\n",[284,489,491],{"class":286,"line":490},13,[284,492,340],{"emptyLinePlaceholder":339},[284,494,496,499,501],{"class":286,"line":495},14,[284,497,498],{"class":294},"r ",[284,500,349],{"class":290},[284,502,503],{"class":294}," QgsSingleCategoryDiagramRenderer()\n",[284,505,507],{"class":286,"line":506},15,[284,508,509],{"class":294},"r.setDiagram(QgsPieDiagram())\n",[284,511,513],{"class":286,"line":512},16,[284,514,515],{"class":294},"r.setDiagramSettings(s)\n",[284,517,519],{"class":286,"line":518},17,[284,520,521],{"class":294},"layer.setDiagramRenderer(r)\n",[284,523,525],{"class":286,"line":524},18,[284,526,527],{"class":294},"layer.setDiagramLayerSettings(QgsDiagramLayerSettings())\n",[284,529,531],{"class":286,"line":530},19,[284,532,533],{"class":294},"layer.triggerRepaint()\n",[14,535,536,539,540,542,543,545,546,548],{},[218,537,538],{},"Breakdown:"," Categories are expressions, so fields go in double quotes and can be combined freely — grouping detailed categories into a few broad ones is usually the first step to a readable diagram. Colours and labels are lists in the same order. Sizes default to millimetres, so diagrams keep their size as the map zooms. Swapping ",[223,541,225],{}," for ",[223,544,229],{}," or ",[223,547,232],{}," changes the chart type with the rest of the configuration unchanged.",[157,550,552],{"id":551},"choosing-the-diagram-type","Choosing the diagram type",[14,554,555],{},"The choice follows from what readers should take away.",[14,557,558,561],{},[218,559,560],{},"Pies"," suit parts of a whole with two to five categories, compared roughly. People judge angles and areas poorly, so pies are weak for precise comparisons between features, and they become unreadable with many thin slices. Grouping categories in the expressions is the most effective improvement.",[14,563,564,567],{},[218,565,566],{},"Histogram bars"," suit comparison. Bar length is the most accurately perceived visual variable, so bars let readers compare the same category between features — industrial jobs here versus there — provided every diagram uses the same scale. That shared scale is the key setting for this type.",[14,569,570,573],{},[218,571,572],{},"Stacked bars"," suit totals and composition together: one bar per feature, its length the total, its segments the parts. Only the first segment shares a baseline across bars, so the category of most interest should go first.",[14,575,576,579],{},[218,577,578],{},"Text diagrams"," suit cases where the numbers themselves are the message — turnout, counts, rates — printed inside a simple shape and placed by the diagram engine along with any other diagrams.",[14,581,582],{},"When none of these fits — too many categories, a time series, a distribution — the answer is usually a full chart beside the map rather than a small one on every feature.",[157,584,586],{"id":585},"size-the-most-powerful-and-most-abused-variable","Size: the most powerful and most abused variable",[14,588,589],{},"Sizing diagrams by an attribute adds magnitude: large districts get large pies. It is also where diagram maps most often mislead.",[14,591,592],{},[29,593,596,599,602,605,608,613,618,622,626,630,633,636,639,642,645,648,652,655,658,661],{"viewBox":594,"role":32,"ariaLabel":595,"xmlns":34},"0 0 760 260","Three rules for honest diagram sizing: scale from zero, scale area not diameter, share one scale across maps",[36,597,598],{},"Three rules for honest sizing",[40,600,601],{},"Rule one: scale from zero, so a value half as large gives a diagram half the size. Rule two: for pies and other area-based diagrams, scale area rather than diameter, otherwise a value four times larger looks sixteen times larger. Rule three: use one scale across a series of maps so equal sizes mean equal values everywhere. Outliers are handled by capping, transforming or an inset, always stated in the legend.",[44,603],{"x":46,"y":46,"width":47,"height":604,"fill":49},"260",[51,606,607],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Zero, area, one scale",[44,609],{"x":61,"y":610,"width":611,"height":612,"rx":65,"fill":66,"stroke":67,"style":68},"56","222","160",[51,614,617],{"x":615,"y":616,"style":73,"fill":67,"textAnchor":57},"135","97.78","from zero",[51,619,621],{"x":615,"y":620,"style":78,"fill":79,"textAnchor":57},"125.78","lower value 0",[51,623,625],{"x":615,"y":624,"style":78,"fill":79,"textAnchor":57},"153.78","lower size 0",[51,627,629],{"x":615,"y":628,"style":78,"fill":88,"textAnchor":57},"181.78","proportional",[44,631],{"x":632,"y":610,"width":611,"height":612,"rx":65,"fill":93,"stroke":94,"style":68},"269",[51,634,635],{"x":53,"y":616,"style":73,"fill":94,"textAnchor":57},"by area",[51,637,638],{"x":53,"y":620,"style":78,"fill":79,"textAnchor":57},"scaleByArea = True",[51,640,641],{"x":53,"y":624,"style":78,"fill":79,"textAnchor":57},"for pies",[51,643,644],{"x":53,"y":628,"style":78,"fill":88,"textAnchor":57},"4× looks 4×",[44,646],{"x":647,"y":610,"width":611,"height":612,"rx":65,"fill":111,"stroke":112,"style":68},"514",[51,649,651],{"x":650,"y":616,"style":73,"fill":112,"textAnchor":57},"625","one scale",[51,653,654],{"x":650,"y":620,"style":78,"fill":79,"textAnchor":57},"shared upper value",[51,656,657],{"x":650,"y":624,"style":78,"fill":79,"textAnchor":57},"across a series",[51,659,660],{"x":650,"y":628,"style":78,"fill":88,"textAnchor":57},"comparable maps",[51,662,664],{"x":53,"y":663,"style":78,"fill":88,"textAnchor":57},"244","outliers: cap, transform or inset — and say which in the legend",[14,666,667,668,671,672,675],{},"Three rules keep sizing honest. Scale from zero, so proportions are preserved; a non-zero minimum size exaggerates differences among small features. For pies and other two-dimensional diagrams, scale area rather than diameter; QGIS's ",[223,669,670],{},"scaleByArea"," setting does exactly that. And when several maps will be compared, compute one upper value over all of them. ",[21,673,674],{"href":190},"Sizing diagrams by attribute"," also deals with outliers — the capital city that shrinks everything else — through capping, transformed scales or an inset map, each of which must be stated in the legend.",[157,677,679],{"id":678},"placement-collisions-and-labels","Placement, collisions and labels",[14,681,682],{},"A map of diagrams is only useful if the diagrams do not pile up on each other. QGIS places diagrams with its labelling engine, which brings the same tools that keep labels tidy.",[275,684,686],{"className":277,"code":685,"language":279,"meta":280,"style":280},"ls = QgsDiagramLayerSettings()\nls.setPlacement(QgsDiagramLayerSettings.OverPoint)\nls.setShowAllDiagrams(False)     # drop colliding diagrams by priority\nls.setPriority(6)\nls.setZIndex(1)\nlayer.setDiagramLayerSettings(ls)\n\ns.scaleBasedVisibility = True\ns.minimumScale = 500000          # only show diagrams when zoomed in beyond 1:500,000\nr.setDiagramSettings(s)\nlayer.triggerRepaint()\n",[223,687,688,698,703,718,728,738,743,747,756,769,773],{"__ignoreMap":280},[284,689,690,693,695],{"class":286,"line":287},[284,691,692],{"class":294},"ls ",[284,694,349],{"class":290},[284,696,697],{"class":294}," QgsDiagramLayerSettings()\n",[284,699,700],{"class":286,"line":304},[284,701,702],{"class":294},"ls.setPlacement(QgsDiagramLayerSettings.OverPoint)\n",[284,704,705,708,711,714],{"class":286,"line":310},[284,706,707],{"class":294},"ls.setShowAllDiagrams(",[284,709,710],{"class":362},"False",[284,712,713],{"class":294},")     ",[284,715,717],{"class":716},"sjoCn","# drop colliding diagrams by priority\n",[284,719,720,723,726],{"class":286,"line":323},[284,721,722],{"class":294},"ls.setPriority(",[284,724,725],{"class":362},"6",[284,727,476],{"class":294},[284,729,730,733,736],{"class":286,"line":336},[284,731,732],{"class":294},"ls.setZIndex(",[284,734,735],{"class":362},"1",[284,737,476],{"class":294},[284,739,740],{"class":286,"line":343},[284,741,742],{"class":294},"layer.setDiagramLayerSettings(ls)\n",[284,744,745],{"class":286,"line":368},[284,746,340],{"emptyLinePlaceholder":339},[284,748,749,752,754],{"class":286,"line":379},[284,750,751],{"class":294},"s.scaleBasedVisibility ",[284,753,349],{"class":290},[284,755,487],{"class":362},[284,757,758,761,763,766],{"class":286,"line":405},[284,759,760],{"class":294},"s.minimumScale ",[284,762,349],{"class":290},[284,764,765],{"class":362}," 500000",[284,767,768],{"class":716},"          # only show diagrams when zoomed in beyond 1:500,000\n",[284,770,771],{"class":286,"line":433},[284,772,515],{"class":294},[284,774,775],{"class":286,"line":458},[284,776,533],{"class":294},[14,778,779,781],{},[218,780,538],{}," Hiding colliding diagrams keeps the map readable at the cost of some missing diagrams; raising the priority of the diagram layer above labels decides which wins when both compete. Scale-based visibility makes diagrams appear only when the map is zoomed in far enough for them to fit. Labels on the same layer treat diagrams as obstacles, so place names move off the charts. For print layouts at a fixed scale, check the exported page rather than the canvas, because the layout's map item renders at its own scale.",[157,783,785],{"id":784},"legends-and-captions","Legends and captions",[14,787,788,789,792],{},"Diagrams need decoding. Category entries — each colour with its label — come from the diagram settings with a single call. Sized diagrams also need a size legend with reference values: round numbers spanning the data, such as 10,000, 50,000 and 100,000, rather than automatically chosen awkward values. In print layouts, a legend item limited to the diagram layer keeps the key focused, and a one-sentence caption stating that area is proportional to the total and naming the largest value prevents the most common misreading. ",[21,790,791],{"href":197},"Adding diagram legends"," builds all three.",[157,794,796],{"id":795},"charts-beside-the-map","Charts beside the map",[14,798,799],{},"Diagrams are small by necessity. When readers need detail — a time series for the area shown, a ranked bar chart of districts, an elevation profile — a full chart beside the map in the print layout is the better tool.",[14,801,802],{},[29,803,806,809,812,814,817,820,824,828,832,834,837,840,843,845,848,851],{"viewBox":804,"role":32,"ariaLabel":805,"xmlns":34},"0 0 760 222","Three ways to add charts to layouts: a matplotlib SVG picture, per-page SVGs in an atlas, and the native chart item on recent releases",[36,807,808],{},"Charts in layouts",[40,810,811],{},"Three ways to put a chart in a layout. A matplotlib SVG as a picture item gives full control and sharp output. One SVG per feature with a data-defined picture source gives a matching chart on every atlas page. The native chart item on recent QGIS releases draws charts from layer attributes without files. Colours and order come from the map's renderer in every case.",[44,813],{"x":46,"y":46,"width":47,"height":611,"fill":49},[51,815,816],{"x":53,"y":54,"style":55,"fill":56,"textAnchor":57},"Picture, per-page picture, or native item",[44,818],{"x":61,"y":610,"width":611,"height":819,"rx":65,"fill":66,"stroke":67,"style":68},"150",[51,821,823],{"x":615,"y":822,"style":73,"fill":67,"textAnchor":57},"106.78","matplotlib SVG",[51,825,827],{"x":615,"y":826,"style":78,"fill":79,"textAnchor":57},"134.78","picture item",[51,829,831],{"x":615,"y":830,"style":78,"fill":88,"textAnchor":57},"162.78","full control",[44,833],{"x":632,"y":610,"width":611,"height":819,"rx":65,"fill":93,"stroke":94,"style":68},[51,835,836],{"x":53,"y":822,"style":73,"fill":94,"textAnchor":57},"per atlas page",[51,838,839],{"x":53,"y":826,"style":78,"fill":79,"textAnchor":57},"data-defined path",[51,841,842],{"x":53,"y":830,"style":78,"fill":88,"textAnchor":57},"one file per feature",[44,844],{"x":647,"y":610,"width":611,"height":819,"rx":65,"fill":111,"stroke":112,"style":68},[51,846,847],{"x":650,"y":822,"style":73,"fill":112,"textAnchor":57},"native chart item",[51,849,850],{"x":650,"y":826,"style":78,"fill":79,"textAnchor":57},"recent releases",[51,852,853],{"x":650,"y":830,"style":78,"fill":88,"textAnchor":57},"no files",[14,855,856,857,860,861,865],{},"Matplotlib charts saved as SVG at their exact print size drop into layouts as picture items and stay sharp in PDF exports. For atlases, one SVG per coverage feature and a data-defined picture source expression give each page its own chart. Recent QGIS releases also include a native chart layout item that draws from layer attributes directly; scripts can test for it and fall back to matplotlib on older LTRs. In every case, reading colours and category order from the map's renderer keeps chart and map visually consistent. ",[21,858,859],{"href":204},"Adding a chart to a print layout"," covers each route, and ",[21,862,864],{"href":863},"\u002Fspatial-data-processing-automation\u002Fpyqgis-and-the-python-data-stack\u002Fplot-layer-data-with-matplotlib-pyqgis\u002F","plotting layer data with matplotlib"," the charts themselves.",[157,867,869],{"id":868},"designing-a-diagram-map-that-works","Designing a diagram map that works",[14,871,872],{},"Beyond the individual settings, a few design habits separate useful diagram maps from cluttered ones.",[14,874,875,878],{},[218,876,877],{},"Keep the base quiet."," Diagrams over a choropleth force readers to decode two colour schemes at once. A pale, neutral fill with thin boundaries lets diagram colours carry the message.",[14,880,881,884],{},[218,882,883],{},"Limit categories."," Four or five categories per diagram is a practical maximum at map size. Group the rest into \"other\", and say what \"other\" contains.",[14,886,887,890],{},[218,888,889],{},"Be consistent across a series."," Same colours, same category order, same scale on every map. Store the finished design as a QML style and reuse it.",[14,892,893,896],{},[218,894,895],{},"Check composition sums."," A pie claims to show a whole; if the category fields do not add up to the real total, the slices misrepresent it. Compare against a total field and add explicit \"other\" or \"not stated\" categories when needed.",[14,898,899,902],{},[218,900,901],{},"Test at print size."," Export a page at the final scale and look at it at 100 %. Overlaps, invisible slivers and illegible text show up immediately.",[275,904,906],{"className":277,"code":905,"language":279,"meta":280,"style":280},"from qgis.core import QgsMapLayer\n\nok, msg = layer.saveNamedStyle(\"\u002Fdata\u002Fstyles\u002Fmode_share_diagrams.qml\",\n                               categories=QgsMapLayer.Diagrams | QgsMapLayer.Symbology)\nprint(\"style saved:\", ok)\n",[223,907,908,919,923,939,956],{"__ignoreMap":280},[284,909,910,912,914,916],{"class":286,"line":287},[284,911,291],{"class":290},[284,913,295],{"class":294},[284,915,298],{"class":290},[284,917,918],{"class":294}," QgsMapLayer\n",[284,920,921],{"class":286,"line":304},[284,922,340],{"emptyLinePlaceholder":339},[284,924,925,928,930,933,936],{"class":286,"line":310},[284,926,927],{"class":294},"ok, msg ",[284,929,349],{"class":290},[284,931,932],{"class":294}," layer.saveNamedStyle(",[284,934,935],{"class":355},"\"\u002Fdata\u002Fstyles\u002Fmode_share_diagrams.qml\"",[284,937,938],{"class":294},",\n",[284,940,941,945,947,950,953],{"class":286,"line":323},[284,942,944],{"class":943},"s9osk","                               categories",[284,946,349],{"class":290},[284,948,949],{"class":294},"QgsMapLayer.Diagrams ",[284,951,952],{"class":290},"|",[284,954,955],{"class":294}," QgsMapLayer.Symbology)\n",[284,957,958,961,964,967],{"class":286,"line":336},[284,959,960],{"class":362},"print",[284,962,963],{"class":294},"(",[284,965,966],{"class":355},"\"style saved:\"",[284,968,969],{"class":294},", ok)\n",[14,971,972,974],{},[218,973,538],{}," Saving only the diagram and symbology categories produces a style that applies cleanly to any layer with the same fields — next year's districts, another city — so a series keeps one design without repeating the configuration in code.",[157,976,978],{"id":977},"automating-diagram-maps","Automating diagram maps",[14,980,981,982,986,987,991],{},"Diagrams are configuration, so they automate well. A script that builds the renderer, computes the shared upper value from the data, applies placement and legend settings, and exports a layout per region or per year produces a consistent map series in minutes. Combined with ",[21,983,985],{"href":984},"\u002Fspatial-data-processing-automation\u002Fautomating-atlas-map-series\u002F","atlas map series"," and per-page charts, it turns a dataset into a complete set of report pages. Because all settings are expressions and numbers, they can also be stored in a configuration file and changed without touching code — the same separation of design and data that makes ",[21,988,990],{"href":989},"\u002Fpyqgis-cartography-visualization\u002Fprogrammatic-layer-styling\u002F","programmatic layer styling"," maintainable.",[157,993,995],{"id":994},"diagrams-or-symbology","Diagrams or symbology?",[14,997,998,999,1003,1004,1008],{},"Not every multi-value question needs a diagram. QGIS symbology can carry two variables at once — colour for one, size for another — and a geometry generator or data-defined symbol can draw surprisingly chart-like marks. Diagrams are the better choice when there are three or more values per feature, when the values are parts of a whole, or when readers should compare categories within each feature. Symbology is better when there are one or two values, when the mark should integrate tightly with the feature's own style, or when the map will be served as vector tiles to web clients that do not render QGIS diagrams. A proportional symbol coloured by a share — circle size for total votes, fill colour for the winning party's margin — often says as much as a pie with far less ink. ",[21,1000,1002],{"href":1001},"\u002Fpyqgis-cartography-visualization\u002Fgraduated-categorized-renderers\u002Fcreate-proportional-symbol-map-pyqgis\u002F","Proportional symbol maps"," and ",[21,1005,1007],{"href":1006},"\u002Fpyqgis-cartography-visualization\u002Fsymbol-layers-and-advanced-symbology\u002Fgeometry-generator-symbol-layer-pyqgis\u002F","geometry generator symbol layers"," cover those alternatives.",[157,1010,1012],{"id":1011},"diagrams-outside-qgis-desktop","Diagrams outside QGIS Desktop",[14,1014,1015,1016,1020],{},"Diagrams render wherever QGIS's rendering engine runs: in standalone scripts that export images, in print layouts generated headless on a server, and in maps published through ",[21,1017,1019],{"href":1018},"\u002Fpyqgis-fundamentals-environment-setup\u002Fheadless-qgis-and-server-automation\u002Fpublish-layers-with-qgis-server-pyqgis\u002F","QGIS Server"," as WMS, where GetMap responses include the diagrams and GetLegendGraphic includes their legend entries. They do not travel into formats rendered by other software: a GeoPackage or vector tile set carries the data, not the diagrams, and web map libraries draw their own symbology. If a diagram map must appear on a web page, publish it as WMS or as pre-rendered tiles, or rebuild the charts on the client.",[157,1022,1024],{"id":1023},"when-a-diagram-map-goes-wrong","When a diagram map goes wrong",[162,1026,1027,1037,1047,1053,1059,1065],{},[165,1028,1029,1032,1033,1036],{},[218,1030,1031],{},"Nothing appears."," ",[223,1034,1035],{},"enabled"," is false, layer settings were never assigned, or the current scale is outside the visibility range.",[165,1038,1039,1042,1043,1046],{},[218,1040,1041],{},"Some features have no diagram."," A category expression returned NULL — wrap fields in ",[223,1044,1045],{},"coalesce"," — or collision handling dropped them.",[165,1048,1049,1052],{},[218,1050,1051],{},"Big features look enormous."," Area scaling is off, so diameter is proportional to value.",[165,1054,1055,1058],{},[218,1056,1057],{},"Maps in a series disagree."," Each computed its own upper value; share one.",[165,1060,1061,1064],{},[218,1062,1063],{},"The legend shows awkward numbers."," Size classes were chosen automatically; set round values.",[165,1066,1067,1070],{},[218,1068,1069],{},"Labels sit on top of diagrams."," Diagram priority is too low or labels are not treating diagrams as obstacles.",[157,1072,1074],{"id":1073},"a-worked-example-commuting-mode-share","A worked example: commuting mode share",[14,1076,1077],{},"Putting the pieces together, a mode-share map for a city's districts takes a few decisions and a short script. The message is composition with magnitude — how people travel, and how many commuters each district has — so the choice is a pie sized by total commuters. Detailed modes are grouped into four categories; colours come from a qualitative palette over a pale base; area scales from zero to the largest district; colliding pies are dropped below 1:150,000; and the legend shows the four categories plus three round reference sizes.",[275,1079,1081],{"className":277,"code":1080,"language":279,"meta":280,"style":280},"from qgis.core import QgsLinearlyInterpolatedDiagramRenderer\n\ngroups = {\"active\": '\"walk\" + \"cycle\"', \"public transport\": '\"bus\" + \"tram\" + \"rail\"',\n          \"car\": '\"car_driver\" + \"car_passenger\"', \"other\": 'coalesce(\"other\", 0)'}\ns.categoryAttributes = [f\"coalesce({e}, 0)\" for e in groups.values()]\ns.categoryLabels = list(groups)\ns.categoryColors = [QColor(c) for c in (\"#15803d\", \"#2563eb\", \"#b45309\", \"#59645f\")]\ns.scaleByArea = True\n\ntotal = \" + \".join(s.categoryAttributes)\nsized = QgsLinearlyInterpolatedDiagramRenderer()\nsized.setDiagram(QgsPieDiagram())\nsized.setClassificationAttributeExpression(total)\nsized.setLowerValue(0)\nsized.setUpperValue(max(f[\"commuters\"] or 0 for f in layer.getFeatures()))\nsized.setLowerSize(QSizeF(0, 0))\nsized.setUpperSize(QSizeF(16, 16))\nsized.setDiagramSettings(s)\nsized.setAttributeLegend(True)\nlayer.setDiagramRenderer(sized)\nlayer.triggerRepaint()\n",[223,1082,1083,1094,1098,1126,1149,1187,1199,1235,1244,1248,1261,1271,1276,1281,1290,1323,1337,1351,1356,1366,1372],{"__ignoreMap":280},[284,1084,1085,1087,1089,1091],{"class":286,"line":287},[284,1086,291],{"class":290},[284,1088,295],{"class":294},[284,1090,298],{"class":290},[284,1092,1093],{"class":294}," QgsLinearlyInterpolatedDiagramRenderer\n",[284,1095,1096],{"class":286,"line":304},[284,1097,340],{"emptyLinePlaceholder":339},[284,1099,1100,1103,1105,1108,1110,1113,1115,1117,1119,1121,1124],{"class":286,"line":310},[284,1101,1102],{"class":294},"groups ",[284,1104,349],{"class":290},[284,1106,1107],{"class":294}," {",[284,1109,443],{"class":355},[284,1111,1112],{"class":294},": ",[284,1114,390],{"class":355},[284,1116,226],{"class":294},[284,1118,448],{"class":355},[284,1120,1112],{"class":294},[284,1122,1123],{"class":355},"'\"bus\" + \"tram\" + \"rail\"'",[284,1125,938],{"class":294},[284,1127,1128,1131,1133,1136,1138,1141,1143,1146],{"class":286,"line":323},[284,1129,1130],{"class":355},"          \"car\"",[284,1132,1112],{"class":294},[284,1134,1135],{"class":355},"'\"car_driver\" + \"car_passenger\"'",[284,1137,226],{"class":294},[284,1139,1140],{"class":355},"\"other\"",[284,1142,1112],{"class":294},[284,1144,1145],{"class":355},"'coalesce(\"other\", 0)'",[284,1147,1148],{"class":294},"}\n",[284,1150,1151,1153,1155,1157,1160,1163,1166,1169,1172,1175,1178,1181,1184],{"class":286,"line":336},[284,1152,382],{"class":294},[284,1154,349],{"class":290},[284,1156,387],{"class":294},[284,1158,1159],{"class":290},"f",[284,1161,1162],{"class":355},"\"coalesce(",[284,1164,1165],{"class":362},"{",[284,1167,1168],{"class":294},"e",[284,1170,1171],{"class":362},"}",[284,1173,1174],{"class":355},", 0)\"",[284,1176,1177],{"class":290}," for",[284,1179,1180],{"class":294}," e ",[284,1182,1183],{"class":290},"in",[284,1185,1186],{"class":294}," groups.values()]\n",[284,1188,1189,1191,1193,1196],{"class":286,"line":343},[284,1190,436],{"class":294},[284,1192,349],{"class":290},[284,1194,1195],{"class":362}," list",[284,1197,1198],{"class":294},"(groups)\n",[284,1200,1201,1203,1205,1208,1211,1214,1216,1218,1220,1222,1224,1226,1228,1230,1233],{"class":286,"line":368},[284,1202,408],{"class":294},[284,1204,349],{"class":290},[284,1206,1207],{"class":294}," [QColor(c) ",[284,1209,1210],{"class":290},"for",[284,1212,1213],{"class":294}," c ",[284,1215,1183],{"class":290},[284,1217,246],{"class":294},[284,1219,416],{"class":355},[284,1221,226],{"class":294},[284,1223,422],{"class":355},[284,1225,226],{"class":294},[284,1227,427],{"class":355},[284,1229,226],{"class":294},[284,1231,1232],{"class":355},"\"#59645f\"",[284,1234,430],{"class":294},[284,1236,1237,1240,1242],{"class":286,"line":379},[284,1238,1239],{"class":294},"s.scaleByArea ",[284,1241,349],{"class":290},[284,1243,487],{"class":362},[284,1245,1246],{"class":286,"line":405},[284,1247,340],{"emptyLinePlaceholder":339},[284,1249,1250,1253,1255,1258],{"class":286,"line":433},[284,1251,1252],{"class":294},"total ",[284,1254,349],{"class":290},[284,1256,1257],{"class":355}," \" + \"",[284,1259,1260],{"class":294},".join(s.categoryAttributes)\n",[284,1262,1263,1266,1268],{"class":286,"line":458},[284,1264,1265],{"class":294},"sized ",[284,1267,349],{"class":290},[284,1269,1270],{"class":294}," QgsLinearlyInterpolatedDiagramRenderer()\n",[284,1272,1273],{"class":286,"line":479},[284,1274,1275],{"class":294},"sized.setDiagram(QgsPieDiagram())\n",[284,1277,1278],{"class":286,"line":490},[284,1279,1280],{"class":294},"sized.setClassificationAttributeExpression(total)\n",[284,1282,1283,1286,1288],{"class":286,"line":495},[284,1284,1285],{"class":294},"sized.setLowerValue(",[284,1287,46],{"class":362},[284,1289,476],{"class":294},[284,1291,1292,1295,1298,1301,1304,1307,1310,1313,1315,1318,1320],{"class":286,"line":506},[284,1293,1294],{"class":294},"sized.setUpperValue(",[284,1296,1297],{"class":362},"max",[284,1299,1300],{"class":294},"(f[",[284,1302,1303],{"class":355},"\"commuters\"",[284,1305,1306],{"class":294},"] ",[284,1308,1309],{"class":290},"or",[284,1311,1312],{"class":362}," 0",[284,1314,1177],{"class":290},[284,1316,1317],{"class":294}," f ",[284,1319,1183],{"class":290},[284,1321,1322],{"class":294}," layer.getFeatures()))\n",[284,1324,1325,1328,1330,1332,1334],{"class":286,"line":512},[284,1326,1327],{"class":294},"sized.setLowerSize(QSizeF(",[284,1329,46],{"class":362},[284,1331,226],{"class":294},[284,1333,46],{"class":362},[284,1335,1336],{"class":294},"))\n",[284,1338,1339,1342,1345,1347,1349],{"class":286,"line":518},[284,1340,1341],{"class":294},"sized.setUpperSize(QSizeF(",[284,1343,1344],{"class":362},"16",[284,1346,226],{"class":294},[284,1348,1344],{"class":362},[284,1350,1336],{"class":294},[284,1352,1353],{"class":286,"line":524},[284,1354,1355],{"class":294},"sized.setDiagramSettings(s)\n",[284,1357,1358,1361,1364],{"class":286,"line":530},[284,1359,1360],{"class":294},"sized.setAttributeLegend(",[284,1362,1363],{"class":362},"True",[284,1365,476],{"class":294},[284,1367,1369],{"class":286,"line":1368},20,[284,1370,1371],{"class":294},"layer.setDiagramRenderer(sized)\n",[284,1373,1375],{"class":286,"line":1374},21,[284,1376,533],{"class":294},[14,1378,1379,1381],{},[218,1380,538],{}," A dictionary of group names to expressions keeps labels and categories in step and makes regrouping a one-line change. The total that sizes each pie is the sum of the same expressions as its slices, so pie area and slice shares always agree. The upper value comes from the data's largest district; for a series of years, replace it with the maximum over all years. Each remaining step — placement, size legend, caption, layout — follows the recipes listed at the top of this guide.",[157,1383,1385],{"id":1384},"key-takeaways","Key takeaways",[162,1387,1388,1391,1394,1400,1403,1406,1409],{},[165,1389,1390],{},"Diagrams are configured by four objects: type, settings, renderer and layer settings.",[165,1392,1393],{},"Choose pies for parts of a whole, bars for comparison, stacked bars for total plus composition, and text for the numbers themselves.",[165,1395,1396,1397,1399],{},"Categories are expressions — group detail into four or five broad categories and wrap fields in ",[223,1398,1045],{},".",[165,1401,1402],{},"Scale size from zero, by area for pies, and with one upper value across a series.",[165,1404,1405],{},"Manage collisions with priorities and scale ranges, and keep the base map quiet.",[165,1407,1408],{},"Give every diagram map category entries, a size legend with round values and a caption.",[165,1410,1411],{},"Use full charts in layouts when readers need detail, with colours taken from the map.",[157,1413,1415],{"id":1414},"frequently-asked-questions","Frequently Asked Questions",[14,1417,1418,1421],{},[218,1419,1420],{},"Are diagrams the same as the heatmap or point cluster renderers?","\nNo. Those are symbology renderers that change how features are drawn; diagrams are an extra layer of charts drawn on top of the features' own symbols.",[14,1423,1424,1427,1428,1399],{},[218,1425,1426],{},"Can diagrams be animated with the temporal controller?","\nYes. Diagrams follow the layer's temporal filtering, so each frame shows the features of that time step; see ",[21,1429,1431],{"href":1430},"\u002Fpyqgis-cartography-visualization\u002Ftemporal-and-3d-visualization\u002Fanimate-with-temporal-controller-pyqgis\u002F","animating with the temporal controller",[14,1433,1434,1437],{},[218,1435,1436],{},"Do diagrams export to vector PDF and SVG?","\nYes. They render as vector graphics in layout exports, so they stay sharp at any zoom.",[14,1439,1440,1443],{},[218,1441,1442],{},"Can I draw diagrams on a point cloud or raster?","\nNo. Diagrams are a vector layer feature. Summarise raster or point cloud values into polygons first, for example with zonal statistics.",[14,1445,1446,1449],{},[218,1447,1448],{},"Is there a limit to how many features can have diagrams?","\nNot technically, but beyond a few hundred on one page the map becomes unreadable. Aggregate to larger units or rely on collision handling and scale limits.",[157,1451,1453],{"id":1452},"related","Related",[162,1455,1456,1461,1468,1475,1482,1489,1494,1499,1504,1509,1514],{},[165,1457,1458,1460],{},[21,1459,24],{"href":23}," — the section this guide belongs to",[165,1462,1463,1467],{},[21,1464,1466],{"href":1465},"\u002Fpyqgis-cartography-visualization\u002Fgraduated-categorized-renderers\u002F","Graduated & Categorized Renderers"," — choropleths and proportional symbols, the single-value alternatives",[165,1469,1470,1474],{},[21,1471,1473],{"href":1472},"\u002Fpyqgis-cartography-visualization\u002Flabeling-and-annotations\u002F","Labeling & Annotations"," — the placement engine diagrams share with labels",[165,1476,1477,1481],{},[21,1478,1480],{"href":1479},"\u002Fspatial-data-processing-automation\u002Fautomated-map-layout-generation\u002F","Automated Map Layout Generation"," — layouts, legends and pictures for charts",[165,1483,1484,1488],{},[21,1485,1487],{"href":1486},"\u002Fspatial-data-processing-automation\u002Fpyqgis-and-the-python-data-stack\u002F","PyQGIS and the Python Data Stack"," — matplotlib and pandas behind layout charts",[165,1490,1491],{},[21,1492,1493],{"href":169},"Add Pie Chart Diagrams to a Layer in PyQGIS",[165,1495,1496],{},[21,1497,1498],{"href":176},"Add Histogram Bar Diagrams in PyQGIS",[165,1500,1501],{},[21,1502,1503],{"href":183},"Add Stacked Bar Diagrams in PyQGIS",[165,1505,1506],{},[21,1507,1508],{"href":190},"Size Diagrams by Attribute in PyQGIS",[165,1510,1511],{},[21,1512,1513],{"href":204},"Add a Chart to a Print Layout in PyQGIS",[165,1515,1516],{},[21,1517,1518],{"href":197},"Add Diagram Legends and Text Diagrams in PyQGIS",[1520,1521,1522],"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":280,"searchDepth":304,"depth":304,"links":1524},[1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540],{"id":159,"depth":304,"text":160},{"id":209,"depth":304,"text":210},{"id":551,"depth":304,"text":552},{"id":585,"depth":304,"text":586},{"id":678,"depth":304,"text":679},{"id":784,"depth":304,"text":785},{"id":795,"depth":304,"text":796},{"id":868,"depth":304,"text":869},{"id":977,"depth":304,"text":978},{"id":994,"depth":304,"text":995},{"id":1011,"depth":304,"text":1012},{"id":1023,"depth":304,"text":1024},{"id":1073,"depth":304,"text":1074},{"id":1384,"depth":304,"text":1385},{"id":1414,"depth":304,"text":1415},{"id":1452,"depth":304,"text":1453},"Show composition and magnitude on maps with PyQGIS diagrams — pies, bars, stacked bars and text diagrams on every feature, honest size scaling, legends that explain them, and charts placed beside maps in print layouts and atlases.","md",{"slug":1544,"type":1545,"breadcrumb":1546,"datePublished":1547,"dateModified":1547},"diagrams-and-charts-on-maps","guide","Diagrams & Charts on Maps","2026-10-02","\u002Fpyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps",{"title":5,"description":1541},"pyqgis-cartography-visualization\u002Fdiagrams-and-charts-on-maps\u002Findex","zwrMi4PU6XjozG0j2aP6sgKLNMoczNdd2-9-ZfdI8W8",1790966252897]