[{"data":1,"prerenderedAt":2616},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter":2581,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter":2590,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter":2595,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter":2596},{"id":4,"title":5,"body":6,"dateModified":2546,"datePublished":2546,"description":2547,"extension":2548,"faq":2549,"keyword":2558,"kind":2559,"meta":2560,"navigation":125,"path":2570,"seo":2571,"slug":2574,"stem":2575,"topics":2576,"type":2579,"__hash__":2580},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter\u002Findex.md","Label Chart Points from Cell Values with XlsxWriter",{"type":7,"value":8,"toc":2534},"minimark",[9,19,24,56,70,74,89,665,668,823,827,835,1116,1123,1367,1371,1374,1795,1798,1802,1809,2139,2147,2151,2154,2349,2356,2419,2423,2458,2462,2469,2473,2479,2485,2491,2497,2501,2530],[10,11,12,13,18],"p",{},"A scatter chart of units sold against margin shows six dots — and every reader's first question is \"which product is that?\". Excel's default labels show the plotted numbers, which the axes already show. What readers want is a label taken from another cell: the product name next to each point, or the margin printed on top of a sales column. XlsxWriter supports custom data labels whose text comes from a cell reference, which Excel 2013 and later display. That feature is not universal, though — LibreOffice ignores such labels — so this page also shows a portable construction that labels points in every application, and a way to label only the points worth pointing out. It belongs to ",[14,15,17],"a",{"href":16},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002F","Building Excel Reports with XlsxWriter",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install xlsxwriter pandas pypdf\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47,50,53],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," xlsxwriter",[35,51,52],{"class":45}," pandas",[35,54,55],{"class":45}," pypdf\n",[10,57,58,61,62,65,66,69],{},[32,59,60],{},"products.xlsx"," lists six products with units sold and margin. LibreOffice (",[32,63,64],{},"soffice",") renders the charts to PDF in Step 5, where ",[32,67,68],{},"pypdf"," reads the text back to check the labels; both are optional.",[20,71,73],{"id":72},"step-1-custom-labels-that-reference-cells","Step 1 — Custom labels that reference cells",[10,75,76,77,80,81,84,85,88],{},"XlsxWriter's ",[32,78,79],{},"data_labels"," option accepts a ",[32,82,83],{},"custom"," list with one entry per point. An entry's ",[32,86,87],{},"value"," can be a formula pointing at a cell:",[25,90,94],{"className":91,"code":92,"language":93,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\nimport xlsxwriter\n\nproducts = pd.read_excel(\"products.xlsx\")\nn = len(products)\n\ndef write_table(book, name=\"Products\"):\n    sheet = book.add_worksheet(name)\n    sheet.write_row(0, 0, list(products.columns))\n    for r, row in enumerate(products.itertuples(index=False), start=1):\n        sheet.write_row(r, 0, row)\n    return sheet\n\nbook = xlsxwriter.Workbook(\"labels_custom.xlsx\")\nsheet = write_table(book)\nchart = book.add_chart({\"type\": \"scatter\"})\nchart.add_series({\n    \"categories\": [\"Products\", 1, 1, n, 1],\n    \"values\": [\"Products\", 1, 2, n, 2],\n    \"marker\": {\"type\": \"circle\", \"size\": 8, \"fill\": {\"color\": \"#4338CA\"}, \"border\": {\"color\": \"#4338CA\"}},\n    \"data_labels\": {\"custom\": [{\"value\": f\"=Products!$A${r}\"} for r in range(2, n + 2)], \"position\": \"right\"},\n})\nchart.set_x_axis({\"name\": \"Units sold\", \"min\": 0})\nchart.set_y_axis({\"name\": \"Margin %\", \"min\": 0})\nchart.set_legend({\"none\": True})\nsheet.insert_chart(\"E2\", chart)\nbook.close()\nprint(\"custom labels:\", [f\"=Products!$A${r}\" for r in range(2, n + 2)])\n","python",[32,95,96,112,120,127,145,160,165,186,197,219,259,270,279,284,300,311,334,340,367,392,450,530,535,560,583,599,611,617],{"__ignoreMap":30},[35,97,98,102,106,109],{"class":37,"line":38},[35,99,101],{"class":100},"s-kum","import",[35,103,105],{"class":104},"skGVy"," pandas ",[35,107,108],{"class":100},"as",[35,110,111],{"class":104}," pd\n",[35,113,115,117],{"class":37,"line":114},2,[35,116,101],{"class":100},[35,118,119],{"class":104}," xlsxwriter\n",[35,121,123],{"class":37,"line":122},3,[35,124,126],{"emptyLinePlaceholder":125},true,"\n",[35,128,130,133,136,139,142],{"class":37,"line":129},4,[35,131,132],{"class":104},"products ",[35,134,135],{"class":100},"=",[35,137,138],{"class":104}," pd.read_excel(",[35,140,141],{"class":45},"\"products.xlsx\"",[35,143,144],{"class":104},")\n",[35,146,148,151,153,157],{"class":37,"line":147},5,[35,149,150],{"class":104},"n ",[35,152,135],{"class":100},[35,154,156],{"class":155},"sP0c6"," len",[35,158,159],{"class":104},"(products)\n",[35,161,163],{"class":37,"line":162},6,[35,164,126],{"emptyLinePlaceholder":125},[35,166,168,171,175,178,180,183],{"class":37,"line":167},7,[35,169,170],{"class":100},"def",[35,172,174],{"class":173},"s_Opv"," write_table",[35,176,177],{"class":104},"(book, name",[35,179,135],{"class":100},[35,181,182],{"class":45},"\"Products\"",[35,184,185],{"class":104},"):\n",[35,187,189,192,194],{"class":37,"line":188},8,[35,190,191],{"class":104},"    sheet ",[35,193,135],{"class":100},[35,195,196],{"class":104}," book.add_worksheet(name)\n",[35,198,200,203,206,209,211,213,216],{"class":37,"line":199},9,[35,201,202],{"class":104},"    sheet.write_row(",[35,204,205],{"class":155},"0",[35,207,208],{"class":104},", ",[35,210,205],{"class":155},[35,212,208],{"class":104},[35,214,215],{"class":155},"list",[35,217,218],{"class":104},"(products.columns))\n",[35,220,222,225,228,231,234,237,241,243,246,249,252,254,257],{"class":37,"line":221},10,[35,223,224],{"class":100},"    for",[35,226,227],{"class":104}," r, row ",[35,229,230],{"class":100},"in",[35,232,233],{"class":155}," enumerate",[35,235,236],{"class":104},"(products.itertuples(",[35,238,240],{"class":239},"sa561","index",[35,242,135],{"class":100},[35,244,245],{"class":155},"False",[35,247,248],{"class":104},"), ",[35,250,251],{"class":239},"start",[35,253,135],{"class":100},[35,255,256],{"class":155},"1",[35,258,185],{"class":104},[35,260,262,265,267],{"class":37,"line":261},11,[35,263,264],{"class":104},"        sheet.write_row(r, ",[35,266,205],{"class":155},[35,268,269],{"class":104},", row)\n",[35,271,273,276],{"class":37,"line":272},12,[35,274,275],{"class":100},"    return",[35,277,278],{"class":104}," sheet\n",[35,280,282],{"class":37,"line":281},13,[35,283,126],{"emptyLinePlaceholder":125},[35,285,287,290,292,295,298],{"class":37,"line":286},14,[35,288,289],{"class":104},"book ",[35,291,135],{"class":100},[35,293,294],{"class":104}," xlsxwriter.Workbook(",[35,296,297],{"class":45},"\"labels_custom.xlsx\"",[35,299,144],{"class":104},[35,301,303,306,308],{"class":37,"line":302},15,[35,304,305],{"class":104},"sheet ",[35,307,135],{"class":100},[35,309,310],{"class":104}," write_table(book)\n",[35,312,314,317,319,322,325,328,331],{"class":37,"line":313},16,[35,315,316],{"class":104},"chart ",[35,318,135],{"class":100},[35,320,321],{"class":104}," book.add_chart({",[35,323,324],{"class":45},"\"type\"",[35,326,327],{"class":104},": ",[35,329,330],{"class":45},"\"scatter\"",[35,332,333],{"class":104},"})\n",[35,335,337],{"class":37,"line":336},17,[35,338,339],{"class":104},"chart.add_series({\n",[35,341,343,346,349,351,353,355,357,359,362,364],{"class":37,"line":342},18,[35,344,345],{"class":45},"    \"categories\"",[35,347,348],{"class":104},": [",[35,350,182],{"class":45},[35,352,208],{"class":104},[35,354,256],{"class":155},[35,356,208],{"class":104},[35,358,256],{"class":155},[35,360,361],{"class":104},", n, ",[35,363,256],{"class":155},[35,365,366],{"class":104},"],\n",[35,368,370,373,375,377,379,381,383,386,388,390],{"class":37,"line":369},19,[35,371,372],{"class":45},"    \"values\"",[35,374,348],{"class":104},[35,376,182],{"class":45},[35,378,208],{"class":104},[35,380,256],{"class":155},[35,382,208],{"class":104},[35,384,385],{"class":155},"2",[35,387,361],{"class":104},[35,389,385],{"class":155},[35,391,366],{"class":104},[35,393,395,398,401,403,405,408,410,413,415,418,420,423,425,428,430,433,436,439,441,443,445,447],{"class":37,"line":394},20,[35,396,397],{"class":45},"    \"marker\"",[35,399,400],{"class":104},": {",[35,402,324],{"class":45},[35,404,327],{"class":104},[35,406,407],{"class":45},"\"circle\"",[35,409,208],{"class":104},[35,411,412],{"class":45},"\"size\"",[35,414,327],{"class":104},[35,416,417],{"class":155},"8",[35,419,208],{"class":104},[35,421,422],{"class":45},"\"fill\"",[35,424,400],{"class":104},[35,426,427],{"class":45},"\"color\"",[35,429,327],{"class":104},[35,431,432],{"class":45},"\"#4338CA\"",[35,434,435],{"class":104},"}, ",[35,437,438],{"class":45},"\"border\"",[35,440,400],{"class":104},[35,442,427],{"class":45},[35,444,327],{"class":104},[35,446,432],{"class":45},[35,448,449],{"class":104},"}},\n",[35,451,453,456,458,461,464,467,469,472,475,479,482,485,488,491,494,497,499,502,505,507,510,513,516,519,522,524,527],{"class":37,"line":452},21,[35,454,455],{"class":45},"    \"data_labels\"",[35,457,400],{"class":104},[35,459,460],{"class":45},"\"custom\"",[35,462,463],{"class":104},": [{",[35,465,466],{"class":45},"\"value\"",[35,468,327],{"class":104},[35,470,471],{"class":100},"f",[35,473,474],{"class":45},"\"=Products!$A$",[35,476,478],{"class":477},"sSjpA","{",[35,480,481],{"class":104},"r",[35,483,484],{"class":477},"}",[35,486,487],{"class":45},"\"",[35,489,490],{"class":104},"} ",[35,492,493],{"class":100},"for",[35,495,496],{"class":104}," r ",[35,498,230],{"class":100},[35,500,501],{"class":155}," range",[35,503,504],{"class":104},"(",[35,506,385],{"class":155},[35,508,509],{"class":104},", n ",[35,511,512],{"class":100},"+",[35,514,515],{"class":155}," 2",[35,517,518],{"class":104},")], ",[35,520,521],{"class":45},"\"position\"",[35,523,327],{"class":104},[35,525,526],{"class":45},"\"right\"",[35,528,529],{"class":104},"},\n",[35,531,533],{"class":37,"line":532},22,[35,534,333],{"class":104},[35,536,538,541,544,546,549,551,554,556,558],{"class":37,"line":537},23,[35,539,540],{"class":104},"chart.set_x_axis({",[35,542,543],{"class":45},"\"name\"",[35,545,327],{"class":104},[35,547,548],{"class":45},"\"Units sold\"",[35,550,208],{"class":104},[35,552,553],{"class":45},"\"min\"",[35,555,327],{"class":104},[35,557,205],{"class":155},[35,559,333],{"class":104},[35,561,563,566,568,570,573,575,577,579,581],{"class":37,"line":562},24,[35,564,565],{"class":104},"chart.set_y_axis({",[35,567,543],{"class":45},[35,569,327],{"class":104},[35,571,572],{"class":45},"\"Margin %\"",[35,574,208],{"class":104},[35,576,553],{"class":45},[35,578,327],{"class":104},[35,580,205],{"class":155},[35,582,333],{"class":104},[35,584,586,589,592,594,597],{"class":37,"line":585},25,[35,587,588],{"class":104},"chart.set_legend({",[35,590,591],{"class":45},"\"none\"",[35,593,327],{"class":104},[35,595,596],{"class":155},"True",[35,598,333],{"class":104},[35,600,602,605,608],{"class":37,"line":601},26,[35,603,604],{"class":104},"sheet.insert_chart(",[35,606,607],{"class":45},"\"E2\"",[35,609,610],{"class":104},", chart)\n",[35,612,614],{"class":37,"line":613},27,[35,615,616],{"class":104},"book.close()\n",[35,618,620,623,625,628,631,633,635,637,639,641,643,646,648,650,652,654,656,658,660,662],{"class":37,"line":619},28,[35,621,622],{"class":155},"print",[35,624,504],{"class":104},[35,626,627],{"class":45},"\"custom labels:\"",[35,629,630],{"class":104},", [",[35,632,471],{"class":100},[35,634,474],{"class":45},[35,636,478],{"class":477},[35,638,481],{"class":104},[35,640,484],{"class":477},[35,642,487],{"class":45},[35,644,645],{"class":100}," for",[35,647,496],{"class":104},[35,649,230],{"class":100},[35,651,501],{"class":155},[35,653,504],{"class":104},[35,655,385],{"class":155},[35,657,509],{"class":104},[35,659,512],{"class":100},[35,661,515],{"class":155},[35,663,664],{"class":104},")])\n",[10,666,667],{},"Each label's text is linked to a product-name cell, so renaming a product in the table renames its label. XlsxWriter writes the reference together with a cached copy of the text, and Excel 2013 and later display it; XlsxWriter's documentation covers the options, including deleting individual labels. In LibreOffice (tested with version 26.2), however, these custom labels are not drawn at all — the points appear unlabelled. If any of your readers use LibreOffice, or the chart is rendered on a server with it, use the construction in Step 2.",[669,670,678,679,678,683,678,687,678,694,678,704,678,715,678,722,678,728,678,734,678,742,678,746,678,751,678,755,678,762,678,766,678,772,678,776,678,782,678,787,678,791,678,795,678,800,678,803,678,808,678,811,678,816,678,818],"svg",{"viewBox":671,"role":672,"ariaLabelledBy":673,"xmlns":676,"style":677},"4 0 752 233","img",[674,675],"lb-methods-t","lb-methods-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[680,681,682],"title",{"id":674},"Two ways to put names on chart points",[684,685,686],"desc",{"id":675},"Custom data labels reference a cell per point and are shown by Excel 2013 and later, but LibreOffice did not draw them. One series per point with series-name labels uses only standard chart features and rendered in LibreOffice as well; it costs one series per point.",[688,689],"rect",{"x":690,"y":205,"width":691,"height":692,"fill":693},"4","752","233","#ffffff",[688,695],{"x":696,"y":697,"width":698,"height":699,"rx":700,"fill":701,"stroke":702,"style":703},"20.0","16.0","351.0","201.0","14","#fdefd8","var(--gold,#b4740a)","stroke-width:2px",[705,706,708],"g",{"transform":707},"translate(182.5,29.0) scale(1.083)",[709,710],"path",{"d":711,"fill":712,"stroke":713,"style":714},"M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1 M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1","none","var(--gold-ink,#7a4e06)","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[716,717,721],"text",{"x":718,"y":719,"style":720},"195.5","78.0","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","custom labels (=Sheet!$A$2)",[37,723],{"x1":724,"y1":725,"x2":726,"y2":725,"stroke":702,"style":727},"36.0","91.0","355.0","stroke-width:1px",[716,729,733],{"x":730,"y":731,"style":732},"60.0","111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","one series, linked to cells",[705,735,737],{"transform":736},"translate(38.5,99.5) scale(0.625)",[709,738],{"d":739,"fill":712,"stroke":740,"style":741},"M5 12.5l4.5 4.5L19 7","var(--teal,#0f9488)","stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[716,743,745],{"x":730,"y":744,"style":732},"137.0","shown by Excel 2013+",[705,747,749],{"transform":748},"translate(38.5,125.5) scale(0.625)",[709,750],{"d":739,"fill":712,"stroke":740,"style":741},[716,752,754],{"x":730,"y":753,"style":732},"163.0","not drawn by LibreOffice",[705,756,758],{"transform":757},"translate(38.5,151.5) scale(0.625)",[709,759],{"d":760,"fill":712,"stroke":761,"style":741},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)",[716,763,765],{"x":730,"y":764,"style":732},"189.0","needs a recent Excel",[705,767,769],{"transform":768},"translate(38.5,177.5) scale(0.625)",[709,770],{"d":771,"fill":712,"stroke":702,"style":741},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[688,773],{"x":774,"y":697,"width":698,"height":699,"rx":700,"fill":775,"stroke":740,"style":703},"389.0","#d9f4f1",[705,777,779],{"transform":778},"translate(551.5,29.0) scale(1.083)",[709,780],{"d":739,"fill":712,"stroke":781,"style":714},"var(--teal-ink,#0b6157)",[716,783,786],{"x":784,"y":719,"style":785},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","one series per point",[37,788],{"x1":789,"y1":725,"x2":790,"y2":725,"stroke":740,"style":727},"405.0","724.0",[716,792,794],{"x":793,"y":731,"style":732},"429.0","standard series-name labels",[705,796,798],{"transform":797},"translate(407.5,99.5) scale(0.625)",[709,799],{"d":739,"fill":712,"stroke":740,"style":741},[716,801,802],{"x":793,"y":744,"style":732},"renders in Excel and LibreOffice",[705,804,806],{"transform":805},"translate(407.5,125.5) scale(0.625)",[709,807],{"d":739,"fill":712,"stroke":740,"style":741},[716,809,810],{"x":793,"y":753,"style":732},"easy to label only some points",[705,812,814],{"transform":813},"translate(407.5,151.5) scale(0.625)",[709,815],{"d":739,"fill":712,"stroke":740,"style":741},[716,817,786],{"x":793,"y":764,"style":732},[705,819,821],{"transform":820},"translate(407.5,177.5) scale(0.625)",[709,822],{"d":771,"fill":712,"stroke":702,"style":741},[20,824,826],{"id":825},"step-2-the-portable-way-one-series-per-point","Step 2 — The portable way: one series per point",[10,828,829,830,834],{},"Every chart application understands a data label that shows the ",[831,832,833],"em",{},"series name",". Make each point its own series, named after its product cell, and turn on series-name labels:",[25,836,838],{"className":91,"code":837,"language":93,"meta":30,"style":30},"book = xlsxwriter.Workbook(\"labels_portable.xlsx\")\nsheet = write_table(book)\nchart = book.add_chart({\"type\": \"scatter\"})\nfor r in range(1, n + 1):\n    chart.add_series({\n        \"name\": [\"Products\", r, 0],                       # the product name cell\n        \"categories\": [\"Products\", r, 1, r, 1],\n        \"values\": [\"Products\", r, 2, r, 2],\n        \"marker\": {\"type\": \"circle\", \"size\": 8, \"fill\": {\"color\": \"#4338CA\"}, \"border\": {\"color\": \"#4338CA\"}},\n        \"data_labels\": {\"series_name\": True, \"position\": \"right\"},\n    })\nchart.set_x_axis({\"name\": \"Units sold\", \"min\": 0})\nchart.set_y_axis({\"name\": \"Margin %\", \"min\": 0})\nchart.set_legend({\"none\": True})\nsheet.insert_chart(\"E2\", chart)\nbook.close()\nprint(n, \"single-point series\")\n",[32,839,840,853,861,877,900,905,926,945,964,1011,1035,1040,1060,1080,1092,1100,1104],{"__ignoreMap":30},[35,841,842,844,846,848,851],{"class":37,"line":38},[35,843,289],{"class":104},[35,845,135],{"class":100},[35,847,294],{"class":104},[35,849,850],{"class":45},"\"labels_portable.xlsx\"",[35,852,144],{"class":104},[35,854,855,857,859],{"class":37,"line":114},[35,856,305],{"class":104},[35,858,135],{"class":100},[35,860,310],{"class":104},[35,862,863,865,867,869,871,873,875],{"class":37,"line":122},[35,864,316],{"class":104},[35,866,135],{"class":100},[35,868,321],{"class":104},[35,870,324],{"class":45},[35,872,327],{"class":104},[35,874,330],{"class":45},[35,876,333],{"class":104},[35,878,879,881,883,885,887,889,891,893,895,898],{"class":37,"line":129},[35,880,493],{"class":100},[35,882,496],{"class":104},[35,884,230],{"class":100},[35,886,501],{"class":155},[35,888,504],{"class":104},[35,890,256],{"class":155},[35,892,509],{"class":104},[35,894,512],{"class":100},[35,896,897],{"class":155}," 1",[35,899,185],{"class":104},[35,901,902],{"class":37,"line":147},[35,903,904],{"class":104},"    chart.add_series({\n",[35,906,907,910,912,914,917,919,922],{"class":37,"line":162},[35,908,909],{"class":45},"        \"name\"",[35,911,348],{"class":104},[35,913,182],{"class":45},[35,915,916],{"class":104},", r, ",[35,918,205],{"class":155},[35,920,921],{"class":104},"],                       ",[35,923,925],{"class":924},"s-wDw","# the product name cell\n",[35,927,928,931,933,935,937,939,941,943],{"class":37,"line":167},[35,929,930],{"class":45},"        \"categories\"",[35,932,348],{"class":104},[35,934,182],{"class":45},[35,936,916],{"class":104},[35,938,256],{"class":155},[35,940,916],{"class":104},[35,942,256],{"class":155},[35,944,366],{"class":104},[35,946,947,950,952,954,956,958,960,962],{"class":37,"line":188},[35,948,949],{"class":45},"        \"values\"",[35,951,348],{"class":104},[35,953,182],{"class":45},[35,955,916],{"class":104},[35,957,385],{"class":155},[35,959,916],{"class":104},[35,961,385],{"class":155},[35,963,366],{"class":104},[35,965,966,969,971,973,975,977,979,981,983,985,987,989,991,993,995,997,999,1001,1003,1005,1007,1009],{"class":37,"line":199},[35,967,968],{"class":45},"        \"marker\"",[35,970,400],{"class":104},[35,972,324],{"class":45},[35,974,327],{"class":104},[35,976,407],{"class":45},[35,978,208],{"class":104},[35,980,412],{"class":45},[35,982,327],{"class":104},[35,984,417],{"class":155},[35,986,208],{"class":104},[35,988,422],{"class":45},[35,990,400],{"class":104},[35,992,427],{"class":45},[35,994,327],{"class":104},[35,996,432],{"class":45},[35,998,435],{"class":104},[35,1000,438],{"class":45},[35,1002,400],{"class":104},[35,1004,427],{"class":45},[35,1006,327],{"class":104},[35,1008,432],{"class":45},[35,1010,449],{"class":104},[35,1012,1013,1016,1018,1021,1023,1025,1027,1029,1031,1033],{"class":37,"line":221},[35,1014,1015],{"class":45},"        \"data_labels\"",[35,1017,400],{"class":104},[35,1019,1020],{"class":45},"\"series_name\"",[35,1022,327],{"class":104},[35,1024,596],{"class":155},[35,1026,208],{"class":104},[35,1028,521],{"class":45},[35,1030,327],{"class":104},[35,1032,526],{"class":45},[35,1034,529],{"class":104},[35,1036,1037],{"class":37,"line":261},[35,1038,1039],{"class":104},"    })\n",[35,1041,1042,1044,1046,1048,1050,1052,1054,1056,1058],{"class":37,"line":272},[35,1043,540],{"class":104},[35,1045,543],{"class":45},[35,1047,327],{"class":104},[35,1049,548],{"class":45},[35,1051,208],{"class":104},[35,1053,553],{"class":45},[35,1055,327],{"class":104},[35,1057,205],{"class":155},[35,1059,333],{"class":104},[35,1061,1062,1064,1066,1068,1070,1072,1074,1076,1078],{"class":37,"line":281},[35,1063,565],{"class":104},[35,1065,543],{"class":45},[35,1067,327],{"class":104},[35,1069,572],{"class":45},[35,1071,208],{"class":104},[35,1073,553],{"class":45},[35,1075,327],{"class":104},[35,1077,205],{"class":155},[35,1079,333],{"class":104},[35,1081,1082,1084,1086,1088,1090],{"class":37,"line":286},[35,1083,588],{"class":104},[35,1085,591],{"class":45},[35,1087,327],{"class":104},[35,1089,596],{"class":155},[35,1091,333],{"class":104},[35,1093,1094,1096,1098],{"class":37,"line":302},[35,1095,604],{"class":104},[35,1097,607],{"class":45},[35,1099,610],{"class":104},[35,1101,1102],{"class":37,"line":313},[35,1103,616],{"class":104},[35,1105,1106,1108,1111,1114],{"class":37,"line":336},[35,1107,622],{"class":155},[35,1109,1110],{"class":104},"(n, ",[35,1112,1113],{"class":45},"\"single-point series\"",[35,1115,144],{"class":104},[10,1117,1118,1119,18],{},"Each series has exactly one point and takes its name from the product cell, so the label still updates when the name changes. Giving every series the same marker style keeps the chart looking like one data set; the legend is turned off because it would list every product. The cost is one series per point, which is fine for the dozens of points a labelled chart can show legibly — and a chart with hundreds of labelled points would be unreadable anyway. Scatter charts in general are covered in ",[14,1120,1122],{"href":1121},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-scatter-chart-in-excel-with-openpyxl\u002F","Create a Scatter Chart in Excel with openpyxl",[669,1124,678,1129,678,1132,678,1135,678,1138,678,1145,678,1149,678,1155,678,1159,678,1163,678,1167,678,1171,678,1175,678,1178,678,1183,678,1187,678,1189,678,1192,678,1194,678,1197,678,1200,678,1202,678,1204,678,1208,678,1210,678,1213,678,1215,678,1218,678,1221,678,1225,678,1227,678,1230,678,1232,678,1235,678,1237,678,1240,678,1243,678,1246,678,1248,678,1251,678,1253,678,1256,678,1258,678,1261,678,1265,678,1270,678,1274,678,1278,678,1282,678,1286,678,1289,678,1293,678,1295,678,1298,678,1300,678,1303,678,1306,678,1310,678,1312,678,1315,678,1317,678,1319,678,1322,678,1326,678,1328,678,1331,678,1333,678,1335,678,1341,678,1345,678,1349,678,1354,678,1362],{"viewBox":1125,"role":672,"ariaLabelledBy":1126,"xmlns":676,"style":677},"4 0 752 192",[1127,1128],"lb-series-t","lb-series-d",[680,1130,1131],{"id":1127},"Six rows become six single-point series",[684,1133,1134],{"id":1128},"On the left the product table with names, units and margins. On the right six chart series, each named by one product cell and holding one point, labelled with its series name.",[688,1136],{"x":690,"y":205,"width":691,"height":1137,"fill":693},"192",[688,1139],{"x":696,"y":1140,"width":1141,"height":1142,"rx":205,"fill":1143,"stroke":1144,"style":727},"40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)",[688,1146],{"x":1147,"y":1140,"width":1148,"height":1142,"rx":205,"fill":1143,"stroke":1144,"style":727},"52.0","66.0",[716,1150,1154],{"x":1151,"y":1152,"style":1153},"85.0","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[688,1156],{"x":1157,"y":1140,"width":1158,"height":1142,"rx":205,"fill":1143,"stroke":1144,"style":727},"118.0","51.5",[716,1160,1162],{"x":1161,"y":1152,"style":1153},"143.7","B",[688,1164],{"x":1165,"y":1140,"width":1166,"height":1142,"rx":205,"fill":1143,"stroke":1144,"style":727},"169.5","75.0",[716,1168,1170],{"x":1169,"y":1152,"style":1153},"207.0","C",[688,1172],{"x":696,"y":1173,"width":1141,"height":1174,"rx":205,"fill":1143,"stroke":1144,"style":727},"64.0","28.0",[716,1176,256],{"x":724,"y":1177,"style":1153},"83.0",[688,1179],{"x":1147,"y":1173,"width":1148,"height":1174,"rx":205,"fill":1180,"stroke":1181,"style":1182},"#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[716,1184,1186],{"x":1151,"y":1177,"style":1185},"font-size:10.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Product",[688,1188],{"x":1157,"y":1173,"width":1158,"height":1174,"rx":205,"fill":1180,"stroke":1181,"style":1182},[716,1190,1191],{"x":1161,"y":1177,"style":1185},"Units",[688,1193],{"x":1165,"y":1173,"width":1166,"height":1174,"rx":205,"fill":1180,"stroke":1181,"style":1182},[716,1195,1196],{"x":1169,"y":1177,"style":1185},"Margin %",[688,1198],{"x":696,"y":1199,"width":1141,"height":1174,"rx":205,"fill":1143,"stroke":1144,"style":727},"92.0",[716,1201,385],{"x":724,"y":731,"style":1153},[688,1203],{"x":1147,"y":1199,"width":1148,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1205,1207],{"x":1151,"y":731,"style":1206},"font-size:10.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Drill",[688,1209],{"x":1157,"y":1199,"width":1158,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1211,1212],{"x":1161,"y":731,"style":1206},"120",[688,1214],{"x":1165,"y":1199,"width":1166,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1216,1217],{"x":1169,"y":731,"style":1206},"32",[688,1219],{"x":696,"y":1220,"width":1141,"height":1174,"rx":205,"fill":1143,"stroke":1144,"style":727},"120.0",[716,1222,1224],{"x":724,"y":1223,"style":1153},"139.0","3",[688,1226],{"x":1147,"y":1220,"width":1148,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1228,1229],{"x":1151,"y":1223,"style":1206},"Saw",[688,1231],{"x":1157,"y":1220,"width":1158,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1233,1234],{"x":1161,"y":1223,"style":1206},"85",[688,1236],{"x":1165,"y":1220,"width":1166,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1238,1239],{"x":1169,"y":1223,"style":1206},"18",[688,1241],{"x":696,"y":1242,"width":1141,"height":1174,"rx":205,"fill":1143,"stroke":1144,"style":727},"148.0",[716,1244,690],{"x":724,"y":1245,"style":1153},"167.0",[688,1247],{"x":1147,"y":1242,"width":1148,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1249,1250],{"x":1151,"y":1245,"style":1206},"Ladder",[688,1252],{"x":1157,"y":1242,"width":1158,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1254,1255],{"x":1161,"y":1245,"style":1206},"35",[688,1257],{"x":1165,"y":1242,"width":1166,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1259,1260],{"x":1169,"y":1245,"style":1206},"41",[688,1262],{"x":1263,"y":1140,"width":1264,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},"509.4","98.5",[716,1266,833],{"x":1267,"y":1268,"style":1269},"558.6","59.0","font-size:10.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle",[688,1271],{"x":1272,"y":1140,"width":1273,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},"607.9","71.1",[716,1275,1277],{"x":1276,"y":1268,"style":1269},"643.5","point",[688,1279],{"x":1280,"y":1140,"width":1281,"height":1174,"rx":205,"fill":1143,"stroke":1144,"style":1182},"679.0","61.0",[716,1283,1285],{"x":1284,"y":1268,"style":1269},"709.5","label",[688,1287],{"x":1263,"y":1288,"width":1264,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},"68.0",[716,1290,1292],{"x":1267,"y":1291,"style":1206},"87.0","=Products!A2",[688,1294],{"x":1272,"y":1288,"width":1273,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1296,1297],{"x":1276,"y":1291,"style":1206},"(120, 32)",[688,1299],{"x":1280,"y":1288,"width":1281,"height":1174,"rx":205,"fill":775,"stroke":740,"style":1182},[716,1301,1207],{"x":1284,"y":1291,"style":1302},"font-size:10.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[688,1304],{"x":1263,"y":1305,"width":1264,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},"96.0",[716,1307,1309],{"x":1267,"y":1308,"style":1206},"115.0","=Products!A3",[688,1311],{"x":1272,"y":1305,"width":1273,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1313,1314],{"x":1276,"y":1308,"style":1206},"(85, 18)",[688,1316],{"x":1280,"y":1305,"width":1281,"height":1174,"rx":205,"fill":775,"stroke":740,"style":1182},[716,1318,1229],{"x":1284,"y":1308,"style":1302},[688,1320],{"x":1263,"y":1321,"width":1264,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},"124.0",[716,1323,1325],{"x":1267,"y":1324,"style":1206},"143.0","=Products!A6",[688,1327],{"x":1272,"y":1321,"width":1273,"height":1174,"rx":205,"fill":693,"stroke":1144,"style":727},[716,1329,1330],{"x":1276,"y":1324,"style":1206},"(35, 41)",[688,1332],{"x":1280,"y":1321,"width":1281,"height":1174,"rx":205,"fill":775,"stroke":740,"style":1182},[716,1334,1250],{"x":1284,"y":1324,"style":1302},[716,1336,1340],{"x":1337,"y":1338,"style":1339},"132.2","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","table",[716,1342,1344],{"x":1343,"y":1338,"style":1339},"624.7","chart series",[37,1346],{"x1":1347,"y1":1305,"x2":1348,"y2":1305,"stroke":1181,"style":703},"254.5","495.4",[1350,1351],"polygon",{"points":1352,"fill":1353},"499.4,96.0 490.4,101.0 490.4,91.0","#5b5cf0",[688,1355],{"x":1356,"y":1357,"width":1358,"height":1359,"rx":1360,"fill":693,"stroke":1144,"style":1361},"287.0","63.0","179.9","22.0","11","stroke-width:1.2px",[716,1363,1366],{"x":1364,"y":719,"style":1365},"376.9","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","one add_series per row",[20,1368,1370],{"id":1369},"step-3-label-only-the-points-that-matter","Step 3 — Label only the points that matter",[10,1372,1373],{},"With many points, labelling all of them clutters the chart. The series-per-point method makes selective labelling easy: give labels only to the series that deserve attention — here the products with the highest margin and the highest volume:",[25,1375,1377],{"className":91,"code":1376,"language":93,"meta":30,"style":30},"top_margin = set(products.nlargest(2, \"Margin %\")[\"Product\"])\ntop_units = set(products.nlargest(1, \"Units\")[\"Product\"])\nhighlight = top_margin | top_units\n\nbook = xlsxwriter.Workbook(\"labels_selected.xlsx\")\nsheet = write_table(book)\nchart = book.add_chart({\"type\": \"scatter\"})\nfor r, product in enumerate(products[\"Product\"], start=1):\n    picked = product in highlight\n    series = {\n        \"name\": [\"Products\", r, 0],\n        \"categories\": [\"Products\", r, 1, r, 1],\n        \"values\": [\"Products\", r, 2, r, 2],\n        \"marker\": {\"type\": \"circle\", \"size\": 9 if picked else 7,\n                   \"fill\": {\"color\": \"#4338CA\" if picked else \"#A5B4FC\"}, \"border\": {\"none\": True}},\n    }\n    if picked:\n        series[\"data_labels\"] = {\"series_name\": True, \"position\": \"above\"}\n    chart.add_series(series)\nchart.set_legend({\"none\": True})\nchart.set_x_axis({\"name\": \"Units sold\", \"min\": 0})\nchart.set_y_axis({\"name\": \"Margin %\", \"min\": 0})\nsheet.insert_chart(\"E2\", chart)\nbook.close()\nprint(\"labelled:\", sorted(highlight))\n",[32,1378,1379,1407,1431,1447,1451,1464,1472,1488,1515,1530,1540,1554,1572,1590,1626,1662,1667,1675,1709,1714,1726,1746,1766,1774,1778],{"__ignoreMap":30},[35,1380,1381,1384,1386,1389,1392,1394,1396,1398,1401,1404],{"class":37,"line":38},[35,1382,1383],{"class":104},"top_margin ",[35,1385,135],{"class":100},[35,1387,1388],{"class":155}," set",[35,1390,1391],{"class":104},"(products.nlargest(",[35,1393,385],{"class":155},[35,1395,208],{"class":104},[35,1397,572],{"class":45},[35,1399,1400],{"class":104},")[",[35,1402,1403],{"class":45},"\"Product\"",[35,1405,1406],{"class":104},"])\n",[35,1408,1409,1412,1414,1416,1418,1420,1422,1425,1427,1429],{"class":37,"line":114},[35,1410,1411],{"class":104},"top_units ",[35,1413,135],{"class":100},[35,1415,1388],{"class":155},[35,1417,1391],{"class":104},[35,1419,256],{"class":155},[35,1421,208],{"class":104},[35,1423,1424],{"class":45},"\"Units\"",[35,1426,1400],{"class":104},[35,1428,1403],{"class":45},[35,1430,1406],{"class":104},[35,1432,1433,1436,1438,1441,1444],{"class":37,"line":122},[35,1434,1435],{"class":104},"highlight ",[35,1437,135],{"class":100},[35,1439,1440],{"class":104}," top_margin ",[35,1442,1443],{"class":100},"|",[35,1445,1446],{"class":104}," top_units\n",[35,1448,1449],{"class":37,"line":129},[35,1450,126],{"emptyLinePlaceholder":125},[35,1452,1453,1455,1457,1459,1462],{"class":37,"line":147},[35,1454,289],{"class":104},[35,1456,135],{"class":100},[35,1458,294],{"class":104},[35,1460,1461],{"class":45},"\"labels_selected.xlsx\"",[35,1463,144],{"class":104},[35,1465,1466,1468,1470],{"class":37,"line":162},[35,1467,305],{"class":104},[35,1469,135],{"class":100},[35,1471,310],{"class":104},[35,1473,1474,1476,1478,1480,1482,1484,1486],{"class":37,"line":167},[35,1475,316],{"class":104},[35,1477,135],{"class":100},[35,1479,321],{"class":104},[35,1481,324],{"class":45},[35,1483,327],{"class":104},[35,1485,330],{"class":45},[35,1487,333],{"class":104},[35,1489,1490,1492,1495,1497,1499,1502,1504,1507,1509,1511,1513],{"class":37,"line":188},[35,1491,493],{"class":100},[35,1493,1494],{"class":104}," r, product ",[35,1496,230],{"class":100},[35,1498,233],{"class":155},[35,1500,1501],{"class":104},"(products[",[35,1503,1403],{"class":45},[35,1505,1506],{"class":104},"], ",[35,1508,251],{"class":239},[35,1510,135],{"class":100},[35,1512,256],{"class":155},[35,1514,185],{"class":104},[35,1516,1517,1520,1522,1525,1527],{"class":37,"line":199},[35,1518,1519],{"class":104},"    picked ",[35,1521,135],{"class":100},[35,1523,1524],{"class":104}," product ",[35,1526,230],{"class":100},[35,1528,1529],{"class":104}," highlight\n",[35,1531,1532,1535,1537],{"class":37,"line":221},[35,1533,1534],{"class":104},"    series ",[35,1536,135],{"class":100},[35,1538,1539],{"class":104}," {\n",[35,1541,1542,1544,1546,1548,1550,1552],{"class":37,"line":261},[35,1543,909],{"class":45},[35,1545,348],{"class":104},[35,1547,182],{"class":45},[35,1549,916],{"class":104},[35,1551,205],{"class":155},[35,1553,366],{"class":104},[35,1555,1556,1558,1560,1562,1564,1566,1568,1570],{"class":37,"line":272},[35,1557,930],{"class":45},[35,1559,348],{"class":104},[35,1561,182],{"class":45},[35,1563,916],{"class":104},[35,1565,256],{"class":155},[35,1567,916],{"class":104},[35,1569,256],{"class":155},[35,1571,366],{"class":104},[35,1573,1574,1576,1578,1580,1582,1584,1586,1588],{"class":37,"line":281},[35,1575,949],{"class":45},[35,1577,348],{"class":104},[35,1579,182],{"class":45},[35,1581,916],{"class":104},[35,1583,385],{"class":155},[35,1585,916],{"class":104},[35,1587,385],{"class":155},[35,1589,366],{"class":104},[35,1591,1592,1594,1596,1598,1600,1602,1604,1606,1608,1611,1614,1617,1620,1623],{"class":37,"line":286},[35,1593,968],{"class":45},[35,1595,400],{"class":104},[35,1597,324],{"class":45},[35,1599,327],{"class":104},[35,1601,407],{"class":45},[35,1603,208],{"class":104},[35,1605,412],{"class":45},[35,1607,327],{"class":104},[35,1609,1610],{"class":155},"9",[35,1612,1613],{"class":100}," if",[35,1615,1616],{"class":104}," picked ",[35,1618,1619],{"class":100},"else",[35,1621,1622],{"class":155}," 7",[35,1624,1625],{"class":104},",\n",[35,1627,1628,1631,1633,1635,1637,1639,1641,1643,1645,1648,1650,1652,1654,1656,1658,1660],{"class":37,"line":302},[35,1629,1630],{"class":45},"                   \"fill\"",[35,1632,400],{"class":104},[35,1634,427],{"class":45},[35,1636,327],{"class":104},[35,1638,432],{"class":45},[35,1640,1613],{"class":100},[35,1642,1616],{"class":104},[35,1644,1619],{"class":100},[35,1646,1647],{"class":45}," \"#A5B4FC\"",[35,1649,435],{"class":104},[35,1651,438],{"class":45},[35,1653,400],{"class":104},[35,1655,591],{"class":45},[35,1657,327],{"class":104},[35,1659,596],{"class":155},[35,1661,449],{"class":104},[35,1663,1664],{"class":37,"line":313},[35,1665,1666],{"class":104},"    }\n",[35,1668,1669,1672],{"class":37,"line":336},[35,1670,1671],{"class":100},"    if",[35,1673,1674],{"class":104}," picked:\n",[35,1676,1677,1680,1683,1686,1688,1691,1693,1695,1697,1699,1701,1703,1706],{"class":37,"line":342},[35,1678,1679],{"class":104},"        series[",[35,1681,1682],{"class":45},"\"data_labels\"",[35,1684,1685],{"class":104},"] ",[35,1687,135],{"class":100},[35,1689,1690],{"class":104}," {",[35,1692,1020],{"class":45},[35,1694,327],{"class":104},[35,1696,596],{"class":155},[35,1698,208],{"class":104},[35,1700,521],{"class":45},[35,1702,327],{"class":104},[35,1704,1705],{"class":45},"\"above\"",[35,1707,1708],{"class":104},"}\n",[35,1710,1711],{"class":37,"line":369},[35,1712,1713],{"class":104},"    chart.add_series(series)\n",[35,1715,1716,1718,1720,1722,1724],{"class":37,"line":394},[35,1717,588],{"class":104},[35,1719,591],{"class":45},[35,1721,327],{"class":104},[35,1723,596],{"class":155},[35,1725,333],{"class":104},[35,1727,1728,1730,1732,1734,1736,1738,1740,1742,1744],{"class":37,"line":452},[35,1729,540],{"class":104},[35,1731,543],{"class":45},[35,1733,327],{"class":104},[35,1735,548],{"class":45},[35,1737,208],{"class":104},[35,1739,553],{"class":45},[35,1741,327],{"class":104},[35,1743,205],{"class":155},[35,1745,333],{"class":104},[35,1747,1748,1750,1752,1754,1756,1758,1760,1762,1764],{"class":37,"line":532},[35,1749,565],{"class":104},[35,1751,543],{"class":45},[35,1753,327],{"class":104},[35,1755,572],{"class":45},[35,1757,208],{"class":104},[35,1759,553],{"class":45},[35,1761,327],{"class":104},[35,1763,205],{"class":155},[35,1765,333],{"class":104},[35,1767,1768,1770,1772],{"class":37,"line":537},[35,1769,604],{"class":104},[35,1771,607],{"class":45},[35,1773,610],{"class":104},[35,1775,1776],{"class":37,"line":562},[35,1777,616],{"class":104},[35,1779,1780,1782,1784,1787,1789,1792],{"class":37,"line":585},[35,1781,622],{"class":155},[35,1783,504],{"class":104},[35,1785,1786],{"class":45},"\"labelled:\"",[35,1788,208],{"class":104},[35,1790,1791],{"class":155},"sorted",[35,1793,1794],{"class":104},"(highlight))\n",[10,1796,1797],{},"Ladder and Drill (highest margins) and Gloves (highest volume) get dark markers and names; the rest are pale and unlabelled, so the eye goes straight to the story. The selection rule lives in code, so next month's chart highlights next month's leaders without anyone editing labels by hand.",[20,1799,1801],{"id":1800},"step-4-labels-from-another-column-on-a-column-chart","Step 4 — Labels from another column on a column chart",[10,1803,1804,1805,1808],{},"The same need appears on column charts: show units as the bars and the ",[831,1806,1807],{},"margin"," as the label on top. With custom labels that is one list of cell references; portably, it is the same series-per-category trick, using a label text column:",[25,1810,1812],{"className":91,"code":1811,"language":93,"meta":30,"style":30},"book = xlsxwriter.Workbook(\"labels_columns.xlsx\")\nsheet = write_table(book)\nsheet.write(0, 3, \"Label\")\nfor r, m in enumerate(products[\"Margin %\"], start=1):\n    sheet.write(r, 3, f\"{m}% margin\")\ncols = book.add_chart({\"type\": \"column\"})\ncols.add_series({\n    \"categories\": [\"Products\", 1, 0, n, 0], \"values\": [\"Products\", 1, 1, n, 1],\n    \"fill\": {\"color\": \"#C7D2FE\"}, \"border\": {\"color\": \"#4338CA\"},\n    \"data_labels\": {\"custom\": [{\"value\": f\"=Products!$D${r}\"} for r in range(2, n + 2)]},\n})\ncols.set_legend({\"none\": True})\ncols.set_title({\"name\": \"Units sold, labelled with margin\"})\nsheet.insert_chart(\"F2\", cols)\nbook.close()\nprint(\"label column:\", [f\"{m}% margin\" for m in products[\"Margin %\"]][:3], \"…\")\n",[32,1813,1814,1827,1835,1853,1878,1903,1921,1926,1969,1997,2047,2051,2064,2078,2088,2092],{"__ignoreMap":30},[35,1815,1816,1818,1820,1822,1825],{"class":37,"line":38},[35,1817,289],{"class":104},[35,1819,135],{"class":100},[35,1821,294],{"class":104},[35,1823,1824],{"class":45},"\"labels_columns.xlsx\"",[35,1826,144],{"class":104},[35,1828,1829,1831,1833],{"class":37,"line":114},[35,1830,305],{"class":104},[35,1832,135],{"class":100},[35,1834,310],{"class":104},[35,1836,1837,1840,1842,1844,1846,1848,1851],{"class":37,"line":122},[35,1838,1839],{"class":104},"sheet.write(",[35,1841,205],{"class":155},[35,1843,208],{"class":104},[35,1845,1224],{"class":155},[35,1847,208],{"class":104},[35,1849,1850],{"class":45},"\"Label\"",[35,1852,144],{"class":104},[35,1854,1855,1857,1860,1862,1864,1866,1868,1870,1872,1874,1876],{"class":37,"line":129},[35,1856,493],{"class":100},[35,1858,1859],{"class":104}," r, m ",[35,1861,230],{"class":100},[35,1863,233],{"class":155},[35,1865,1501],{"class":104},[35,1867,572],{"class":45},[35,1869,1506],{"class":104},[35,1871,251],{"class":239},[35,1873,135],{"class":100},[35,1875,256],{"class":155},[35,1877,185],{"class":104},[35,1879,1880,1883,1885,1887,1889,1891,1893,1896,1898,1901],{"class":37,"line":147},[35,1881,1882],{"class":104},"    sheet.write(r, ",[35,1884,1224],{"class":155},[35,1886,208],{"class":104},[35,1888,471],{"class":100},[35,1890,487],{"class":45},[35,1892,478],{"class":477},[35,1894,1895],{"class":104},"m",[35,1897,484],{"class":477},[35,1899,1900],{"class":45},"% margin\"",[35,1902,144],{"class":104},[35,1904,1905,1908,1910,1912,1914,1916,1919],{"class":37,"line":162},[35,1906,1907],{"class":104},"cols ",[35,1909,135],{"class":100},[35,1911,321],{"class":104},[35,1913,324],{"class":45},[35,1915,327],{"class":104},[35,1917,1918],{"class":45},"\"column\"",[35,1920,333],{"class":104},[35,1922,1923],{"class":37,"line":167},[35,1924,1925],{"class":104},"cols.add_series({\n",[35,1927,1928,1930,1932,1934,1936,1938,1940,1942,1944,1946,1948,1951,1953,1955,1957,1959,1961,1963,1965,1967],{"class":37,"line":188},[35,1929,345],{"class":45},[35,1931,348],{"class":104},[35,1933,182],{"class":45},[35,1935,208],{"class":104},[35,1937,256],{"class":155},[35,1939,208],{"class":104},[35,1941,205],{"class":155},[35,1943,361],{"class":104},[35,1945,205],{"class":155},[35,1947,1506],{"class":104},[35,1949,1950],{"class":45},"\"values\"",[35,1952,348],{"class":104},[35,1954,182],{"class":45},[35,1956,208],{"class":104},[35,1958,256],{"class":155},[35,1960,208],{"class":104},[35,1962,256],{"class":155},[35,1964,361],{"class":104},[35,1966,256],{"class":155},[35,1968,366],{"class":104},[35,1970,1971,1974,1976,1978,1980,1983,1985,1987,1989,1991,1993,1995],{"class":37,"line":199},[35,1972,1973],{"class":45},"    \"fill\"",[35,1975,400],{"class":104},[35,1977,427],{"class":45},[35,1979,327],{"class":104},[35,1981,1982],{"class":45},"\"#C7D2FE\"",[35,1984,435],{"class":104},[35,1986,438],{"class":45},[35,1988,400],{"class":104},[35,1990,427],{"class":45},[35,1992,327],{"class":104},[35,1994,432],{"class":45},[35,1996,529],{"class":104},[35,1998,1999,2001,2003,2005,2007,2009,2011,2013,2016,2018,2020,2022,2024,2026,2028,2030,2032,2034,2036,2038,2040,2042,2044],{"class":37,"line":221},[35,2000,455],{"class":45},[35,2002,400],{"class":104},[35,2004,460],{"class":45},[35,2006,463],{"class":104},[35,2008,466],{"class":45},[35,2010,327],{"class":104},[35,2012,471],{"class":100},[35,2014,2015],{"class":45},"\"=Products!$D$",[35,2017,478],{"class":477},[35,2019,481],{"class":104},[35,2021,484],{"class":477},[35,2023,487],{"class":45},[35,2025,490],{"class":104},[35,2027,493],{"class":100},[35,2029,496],{"class":104},[35,2031,230],{"class":100},[35,2033,501],{"class":155},[35,2035,504],{"class":104},[35,2037,385],{"class":155},[35,2039,509],{"class":104},[35,2041,512],{"class":100},[35,2043,515],{"class":155},[35,2045,2046],{"class":104},")]},\n",[35,2048,2049],{"class":37,"line":261},[35,2050,333],{"class":104},[35,2052,2053,2056,2058,2060,2062],{"class":37,"line":272},[35,2054,2055],{"class":104},"cols.set_legend({",[35,2057,591],{"class":45},[35,2059,327],{"class":104},[35,2061,596],{"class":155},[35,2063,333],{"class":104},[35,2065,2066,2069,2071,2073,2076],{"class":37,"line":281},[35,2067,2068],{"class":104},"cols.set_title({",[35,2070,543],{"class":45},[35,2072,327],{"class":104},[35,2074,2075],{"class":45},"\"Units sold, labelled with margin\"",[35,2077,333],{"class":104},[35,2079,2080,2082,2085],{"class":37,"line":286},[35,2081,604],{"class":104},[35,2083,2084],{"class":45},"\"F2\"",[35,2086,2087],{"class":104},", cols)\n",[35,2089,2090],{"class":37,"line":302},[35,2091,616],{"class":104},[35,2093,2094,2096,2098,2101,2103,2105,2107,2109,2111,2113,2115,2117,2120,2122,2125,2127,2130,2132,2134,2137],{"class":37,"line":313},[35,2095,622],{"class":155},[35,2097,504],{"class":104},[35,2099,2100],{"class":45},"\"label column:\"",[35,2102,630],{"class":104},[35,2104,471],{"class":100},[35,2106,487],{"class":45},[35,2108,478],{"class":477},[35,2110,1895],{"class":104},[35,2112,484],{"class":477},[35,2114,1900],{"class":45},[35,2116,645],{"class":100},[35,2118,2119],{"class":104}," m ",[35,2121,230],{"class":100},[35,2123,2124],{"class":104}," products[",[35,2126,572],{"class":45},[35,2128,2129],{"class":104},"]][:",[35,2131,1224],{"class":155},[35,2133,1506],{"class":104},[35,2135,2136],{"class":45},"\"…\"",[35,2138,144],{"class":104},[10,2140,2141,2142,2146],{},"A helper column holds the formatted label text, and each bar's custom label points at its row. In Excel the bars show \"32% margin\", \"18% margin\" and so on; for a LibreOffice-safe version, use one series per bar with series names taken from the label column, exactly as in Step 2. Custom labels can also carry fixed text, a font and a position per point — see ",[14,2143,2145],{"href":2144},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fstyle-chart-colors-and-data-labels-with-openpyxl\u002F","Style Chart Colours and Data Labels with openpyxl"," for the equivalent openpyxl options.",[20,2148,2150],{"id":2149},"step-5-check-that-the-labels-are-drawn","Step 5 — Check that the labels are drawn",[10,2152,2153],{},"Labels that render in one application and not another are easy to miss. Render each file to PDF and look for the product names on the page:",[25,2155,2157],{"className":91,"code":2156,"language":93,"meta":30,"style":30},"import subprocess\nfrom pypdf import PdfReader\n\ndef label_count(xlsx, words):\n    subprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"pdf\", xlsx], check=True, capture_output=True)\n    text = PdfReader(xlsx.replace(\".xlsx\", \".pdf\")).pages[0].extract_text()\n    return {w: text.count(w) for w in words}\n\nnames = list(products[\"Product\"])\nfor f in (\"labels_custom.xlsx\", \"labels_portable.xlsx\", \"labels_selected.xlsx\"):\n    print(f\"{f:22}\", label_count(f, names))\n",[32,2158,2159,2166,2179,2183,2193,2237,2263,2280,2284,2300,2324],{"__ignoreMap":30},[35,2160,2161,2163],{"class":37,"line":38},[35,2162,101],{"class":100},[35,2164,2165],{"class":104}," subprocess\n",[35,2167,2168,2171,2174,2176],{"class":37,"line":114},[35,2169,2170],{"class":100},"from",[35,2172,2173],{"class":104}," pypdf ",[35,2175,101],{"class":100},[35,2177,2178],{"class":104}," PdfReader\n",[35,2180,2181],{"class":37,"line":122},[35,2182,126],{"emptyLinePlaceholder":125},[35,2184,2185,2187,2190],{"class":37,"line":129},[35,2186,170],{"class":100},[35,2188,2189],{"class":173}," label_count",[35,2191,2192],{"class":104},"(xlsx, words):\n",[35,2194,2195,2198,2201,2203,2206,2208,2211,2213,2216,2219,2222,2224,2226,2228,2231,2233,2235],{"class":37,"line":147},[35,2196,2197],{"class":104},"    subprocess.run([",[35,2199,2200],{"class":45},"\"soffice\"",[35,2202,208],{"class":104},[35,2204,2205],{"class":45},"\"--headless\"",[35,2207,208],{"class":104},[35,2209,2210],{"class":45},"\"--convert-to\"",[35,2212,208],{"class":104},[35,2214,2215],{"class":45},"\"pdf\"",[35,2217,2218],{"class":104},", xlsx], ",[35,2220,2221],{"class":239},"check",[35,2223,135],{"class":100},[35,2225,596],{"class":155},[35,2227,208],{"class":104},[35,2229,2230],{"class":239},"capture_output",[35,2232,135],{"class":100},[35,2234,596],{"class":155},[35,2236,144],{"class":104},[35,2238,2239,2242,2244,2247,2250,2252,2255,2258,2260],{"class":37,"line":162},[35,2240,2241],{"class":104},"    text ",[35,2243,135],{"class":100},[35,2245,2246],{"class":104}," PdfReader(xlsx.replace(",[35,2248,2249],{"class":45},"\".xlsx\"",[35,2251,208],{"class":104},[35,2253,2254],{"class":45},"\".pdf\"",[35,2256,2257],{"class":104},")).pages[",[35,2259,205],{"class":155},[35,2261,2262],{"class":104},"].extract_text()\n",[35,2264,2265,2267,2270,2272,2275,2277],{"class":37,"line":167},[35,2266,275],{"class":100},[35,2268,2269],{"class":104}," {w: text.count(w) ",[35,2271,493],{"class":100},[35,2273,2274],{"class":104}," w ",[35,2276,230],{"class":100},[35,2278,2279],{"class":104}," words}\n",[35,2281,2282],{"class":37,"line":188},[35,2283,126],{"emptyLinePlaceholder":125},[35,2285,2286,2289,2291,2294,2296,2298],{"class":37,"line":199},[35,2287,2288],{"class":104},"names ",[35,2290,135],{"class":100},[35,2292,2293],{"class":155}," list",[35,2295,1501],{"class":104},[35,2297,1403],{"class":45},[35,2299,1406],{"class":104},[35,2301,2302,2304,2307,2309,2312,2314,2316,2318,2320,2322],{"class":37,"line":221},[35,2303,493],{"class":100},[35,2305,2306],{"class":104}," f ",[35,2308,230],{"class":100},[35,2310,2311],{"class":104}," (",[35,2313,297],{"class":45},[35,2315,208],{"class":104},[35,2317,850],{"class":45},[35,2319,208],{"class":104},[35,2321,1461],{"class":45},[35,2323,185],{"class":104},[35,2325,2326,2329,2331,2333,2335,2337,2339,2342,2344,2346],{"class":37,"line":261},[35,2327,2328],{"class":155},"    print",[35,2330,504],{"class":104},[35,2332,471],{"class":100},[35,2334,487],{"class":45},[35,2336,478],{"class":477},[35,2338,471],{"class":104},[35,2340,2341],{"class":100},":22",[35,2343,484],{"class":477},[35,2345,487],{"class":45},[35,2347,2348],{"class":104},", label_count(f, names))\n",[10,2350,2351,2352,2355],{},"Each product name appears once in the table on every page. In the custom-label file it appears ",[831,2353,2354],{},"only"," once — LibreOffice drew no labels — while in the portable file every name appears twice, once in the table and once on the chart, and in the selected file only the three highlighted names appear twice. A check of this kind in a test catches a chart whose labels silently vanished, in whichever application your pipeline renders with.",[669,2357,678,2363,678,2366,678,2369,678,2373,678,2377,678,2383,678,2389,678,2394,678,2397,678,2400,678,2403,678,2408,678,2410,678,2414,678,2416],{"viewBox":2358,"role":672,"ariaLabelledBy":2359,"xmlns":676,"style":2362},"4 0 744 140",[2360,2361],"lb-check-t","lb-check-d","width:100%;max-width:744px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[680,2364,2365],{"id":2360},"Product names found in the rendered page",[684,2367,2368],{"id":2361},"Number of times the name Drill appears in each rendered PDF. In the custom-label file it appears once, in the table only. In the portable and selected-label files it appears twice, in the table and as a chart label.",[688,2370],{"x":690,"y":205,"width":2371,"height":2372,"fill":693},"744","140",[688,2374],{"x":696,"y":697,"width":2375,"height":1174,"rx":2376,"fill":1143,"stroke":1144,"style":727},"202.4","7",[716,2378,2382],{"x":2379,"y":2380,"style":2381},"121.2","34.5","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","custom labels (LibreOffice)",[688,2384],{"x":2385,"y":697,"width":2386,"height":1174,"rx":2376,"fill":2387,"stroke":2388,"style":1182},"232.4","181.4","#fce9e9","var(--danger,#dc2626)",[716,2390,2393],{"x":2391,"y":2380,"style":2392},"421.8","font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:start","1 · table only",[688,2395],{"x":696,"y":2396,"width":2375,"height":1174,"rx":2376,"fill":1143,"stroke":1144,"style":727},"56.0",[716,2398,786],{"x":2379,"y":2399,"style":2381},"74.5",[688,2401],{"x":2385,"y":2396,"width":2402,"height":1174,"rx":2376,"fill":775,"stroke":740,"style":1182},"362.7",[716,2404,2407],{"x":2405,"y":2399,"style":2406},"603.2","font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:start","2 · table + label",[688,2409],{"x":696,"y":1305,"width":2375,"height":1174,"rx":2376,"fill":1143,"stroke":1144,"style":727},[716,2411,2413],{"x":2379,"y":2412,"style":2381},"114.5","selected labels",[688,2415],{"x":2385,"y":1305,"width":2402,"height":1174,"rx":2376,"fill":775,"stroke":740,"style":1182},[716,2417,2418],{"x":2405,"y":2412,"style":2406},"2 · Drill is highlighted",[20,2420,2422],{"id":2421},"common-pitfalls","Common pitfalls",[2424,2425,2426,2434,2440,2446,2452],"ul",{},[2427,2428,2429,2433],"li",{},[2430,2431,2432],"strong",{},"Assuming custom labels render everywhere."," Excel 2013+ shows them; LibreOffice did not.",[2427,2435,2436,2439],{},[2430,2437,2438],{},"Labels showing values instead of names."," Default labels show the y value; use custom or series-name labels.",[2427,2441,2442,2445],{},[2430,2443,2444],{},"A legend listing every point."," With one series per point, turn the legend off.",[2427,2447,2448,2451],{},[2430,2449,2450],{},"Labelling everything."," Highlight the few points that matter; dense labels overlap.",[2427,2453,2454,2457],{},[2430,2455,2456],{},"Hard-coded label text."," Reference cells or derive the text in code so labels stay in step with the data.",[20,2459,2461],{"id":2460},"conclusion","Conclusion",[10,2463,2464,2465,2468],{},"To name chart points, XlsxWriter's custom data labels can reference a cell per point (",[32,2466,2467],{},"{\"value\": \"=Products!$A$2\"}","), which Excel 2013 and later display but LibreOffice ignores. For labels that render everywhere, give each point its own series named after its cell and turn on series-name labels — a construction that also makes it easy to label only the points that matter. Use a helper column for composed label text, and check rendered output for the names so missing labels are caught.",[20,2470,2472],{"id":2471},"frequently-asked-questions","Frequently asked questions",[10,2474,2475,2478],{},[2430,2476,2477],{},"How do I label Excel chart points with names from cells using XlsxWriter?","\nAdd data_labels with a custom list to the series, one entry per point, each with a value formula such as =Products!$A$2. Excel 2013 and later show the text of the referenced cell.",[10,2480,2481,2484],{},[2430,2482,2483],{},"Why don't my XlsxWriter custom data labels show in LibreOffice?","\nLibreOffice did not draw custom data labels that reference cells in our test. Use one series per point with series_name labels, which renders in both Excel and LibreOffice.",[10,2486,2487,2490],{},[2430,2488,2489],{},"How do I label only some points of a chart?","\nCreate each point as its own series and add data labels only to the series you want to highlight, for example the top values selected with nlargest in pandas.",[10,2492,2493,2496],{},[2430,2494,2495],{},"Can a column chart show a label from a different column?","\nYes. Write the label text in a helper column and use custom data labels that reference it, or, for full portability, one series per category named from that column with series_name labels.",[20,2498,2500],{"id":2499},"related","Related",[2424,2502,2503,2509,2516,2523],{},[2427,2504,2505,2506,2508],{},"Up one level: ",[14,2507,17],{"href":16}," — formatted reports and charts.",[2427,2510,2511,2515],{},[14,2512,2514],{"href":2513},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fadd-a-chart-to-an-excel-file-with-xlsxwriter\u002F","Add a Chart to an Excel File with xlsxwriter"," — chart basics in XlsxWriter.",[2427,2517,2518,2522],{},[14,2519,2521],{"href":2520},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-bubble-chart-with-openpyxl\u002F","Create a Bubble Chart with openpyxl"," — a third dimension on a scatter.",[2427,2524,2525,2529],{},[14,2526,2528],{"href":2527},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fcreate-a-bullet-chart-in-excel-with-python\u002F","Create a Bullet Chart in Excel with Python"," — another chart built from several series.",[2531,2532,2533],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":30,"searchDepth":114,"depth":114,"links":2535},[2536,2537,2538,2539,2540,2541,2542,2543,2544,2545],{"id":22,"depth":114,"text":23},{"id":72,"depth":114,"text":73},{"id":825,"depth":114,"text":826},{"id":1369,"depth":114,"text":1370},{"id":1800,"depth":114,"text":1801},{"id":2149,"depth":114,"text":2150},{"id":2421,"depth":114,"text":2422},{"id":2460,"depth":114,"text":2461},{"id":2471,"depth":114,"text":2472},{"id":2499,"depth":114,"text":2500},"2026-10-02","Put product names, regions or comments on chart points instead of bare numbers: XlsxWriter custom data labels that reference cells (shown by Excel, ignored by LibreOffice), a portable one-series-per-point technique whose series-name labels render everywhere, labelling only the points that matter, labels from a different column on a column chart, and a test that the labels are really drawn.","md",[2550,2552,2554,2556],{"q":2477,"a":2551},"Add data_labels with a custom list to the series, one entry per point, each with a value formula such as =Products!$A$2. Excel 2013 and later show the text of the referenced cell.",{"q":2483,"a":2553},"LibreOffice did not draw custom data labels that reference cells in our test. Use one series per point with series_name labels, which renders in both Excel and LibreOffice.",{"q":2489,"a":2555},"Create each point as its own series and add data labels only to the series you want to highlight, for example the top values selected with nlargest in pandas.",{"q":2495,"a":2557},"Yes. Write the label text in a helper column and use custom data labels that reference it, or, for full portability, one series per category named from that column with series_name labels.","label chart points from cell values with xlsxwriter",null,{"breadcrumb":2561},[2562,2565,2568],{"name":2563,"item":2564},"Home","\u002F",{"name":2566,"item":2567},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":2569,"item":16},"Building Excel Reports with xlsxwriter","\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter",{"title":2572,"description":2573},"Label Excel Chart Points from Cell Values with XlsxWriter","Name the points of an Excel scatter or column chart from Python: data_labels custom with =Sheet!$A$2 references, the portable one-series-per-point method with series_name labels, labelling only top points, and checking rendered labels.","label-chart-points-from-cell-values-with-xlsxwriter","formatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Flabel-chart-points-from-cell-values-with-xlsxwriter\u002Findex",[2577,2578],"charts-and-images","xlsxwriter","how-to","-MgcmwY1Qi3G2SAaN7KD0kYDKP8BhEc6acXDWrSuuGI",[2582,2586],{"title":2583,"path":2584,"stem":2585,"children":-1},"Insert Checkboxes in Excel with xlsxwriter","\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Finsert-checkboxes-with-xlsxwriter","formatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Finsert-checkboxes-with-xlsxwriter\u002Findex",{"title":2587,"path":2588,"stem":2589,"children":-1},"Set Print Options, Headers and Footers with XlsxWriter","\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fset-print-options-headers-and-footers-with-xlsxwriter","formatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fset-print-options-headers-and-footers-with-xlsxwriter\u002Findex",[2591,2593],{"path":2592,"title":2569},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter",{"path":2594,"title":2566},"\u002Fformatting-and-charting-excel-reports-with-python",[],[2597,2600,2603,2606,2610,2613],{"path":2598,"title":2599,"kind":2579},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-dashboard-sheet-with-charts-from-multiple-tabs","Build a Dashboard Sheet with Charts from Multiple Tabs",{"path":2601,"title":2602,"kind":2579},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-rolling-12-month-chart-on-an-excel-dashboard","Build a Rolling 12-Month Chart on an Excel Dashboard",{"path":2604,"title":2605,"kind":2579},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fkeep-charts-and-images-when-filling-an-excel-template","Keep Charts and Images When Filling an Excel Template",{"path":2607,"title":2608,"kind":2609},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl","Creating Charts in Excel with openpyxl","guide",{"path":2611,"title":2612,"kind":2579},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-a-combo-chart-with-a-secondary-axis-in-openpyxl","Add a Combo Chart with a Secondary Axis in openpyxl",{"path":2614,"title":2615,"kind":2579},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fadd-a-data-table-below-an-excel-chart","Add a Data Table Below an Excel Chart",1790972108623]