{"id":612,"date":"2026-05-14T11:56:16","date_gmt":"2026-05-14T03:56:16","guid":{"rendered":"https:\/\/xlwings.net\/blog\/?p=612"},"modified":"2026-03-24T06:11:32","modified_gmt":"2026-03-24T06:11:32","slug":"how-to-create-custom-scatter-bar-chart-using-xlwings","status":"publish","type":"post","link":"https:\/\/xlwings.net\/blog\/how-to-create-custom-scatter-bar-chart-using-xlwings\/","title":{"rendered":"How To Create Custom Scatter Bar Chart Using xlwings?"},"content":{"rendered":"<p style=\"margin: 0in; font-size: 16.0pt;\"><span lang=\"zh-CN\" style=\"font-family: 'Microsoft YaHei';\">\u3010<\/span><span lang=\"en-US\" style=\"font-weight: bold; font-family: Calibri;\">Example<\/span><span lang=\"zh-CN\" style=\"font-family: 'Microsoft YaHei';\">\u3011<\/span><\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"880\" height=\"756\" src=\"https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-12.jpg\" alt=\"\" class=\"wp-image-1472\" srcset=\"https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-12.jpg 880w, https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-12-300x258.jpg 300w, https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-12-768x660.jpg 768w\" sizes=\"auto, (max-width: 880px) 100vw, 880px\" \/><\/figure>\n\n\n\n<p>\u3010<strong>Code<\/strong>\u3011<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import xlwings as xw\nimport numpy as np\nimport os\n\ndef set_style(cht):\n    cht.ChartArea.Format.Line.Visible=False\n    cht.PlotArea.Format.Fill.Visible = False\n    cht.PlotArea.Format.Line.Visible = True\n    cht.PlotArea.Format.Line.ForeColor.RGB=xw.utils.rgb_to_int((200,200,200))\n    #cht.PlotArea.Format.Line.ForeColor.ObjectThemeColor = msoThemeColorText1\n    ax1 = cht.Axes(1)\n    ax2 = cht.Axes(2)\n    ax1.HasTitle = True\n    ax1.AxisTitle.Text = 'Categories'\n    ax1.AxisTitle.Font.Size = 10\n    ax1.TickLabels.Font.Size = 8\n    #ax1.TickLabels.NumberFormat = '0.00'\n    ax1.HasMajorGridlines = False\n    ax2.HasTitle = True\n    ax2.AxisTitle.Text = 'Values'\n    ax2.AxisTitle.Font.Size = 10\n    ax2.TickLabels.Font.Size = 8\n    ax2.HasMajorGridlines = False\n    cht.HasTitle = True\n    #cht.ChartTitle.Caption = 'Plot'\n    #cht.ChartTitle.Font.Size = 12\n\ndef draw_bar(cht,y,n,x,r,g,b,w,grad):\n    aveg=np.mean(y)\n    \n    pt=&#91;&#91;0 for _ in range(2)] for _ in range(5)]\n    pt&#91;0]&#91;0]=shape_x(cht,x-w\/2)\n    pt&#91;0]&#91;1]=shape_y(cht,cht.Axes(2).MinimumScale)\n    pt&#91;1]&#91;0]=shape_x(cht,x+w\/2)\n    pt&#91;1]&#91;1]=shape_y(cht,cht.Axes(2).MinimumScale)\n    pt&#91;2]&#91;0]=shape_x(cht,x+w\/2)\n    pt&#91;2]&#91;1]=shape_y(cht,aveg)\n    pt&#91;3]&#91;0]=shape_x(cht,x-w\/2)\n    pt&#91;3]&#91;1]=shape_y(cht,aveg)\n    pt&#91;4]&#91;0]=pt&#91;0]&#91;0]\n    pt&#91;4]&#91;1]=pt&#91;0]&#91;1]\n    shp=cht.Shapes.AddPolyline(pt)\n    if grad:\n        shp.Fill.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n        shp.Fill.OneColorGradient(1,1,1)\n        shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n        shp.Line.Weight=1.5\n    else:\n        shp.Fill.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n        shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n        shp.Line.Weight=1.5\n\ndef draw_rnd_scatter(cht,x,y,n,w,r,g,b):\n    rd=&#91;]\n    for i in range(n):\n        rd.append(x-w\/2+w*np.random.rand(1)&#91;0])\n    for i in range(n):\n        bx=shape_x(cht,rd&#91;i])\n        by=shape_y(cht,y&#91;i])\n        ex=cht.PlotArea.InsideWidth\/(cht.Axes(1).MaximumScale- \\\n        cht.Axes(1).MinimumScale)*0.09\n        ey=ex\n        shp=cht.Shapes.AddShape(9,bx,by,ex,ey)\n        shp.Fill.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n        shp.Line.Weight=1\n        shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))\n\nroot=os.getcwd()\napp=xw.App(visible=True,add_book=False)\nwb=app.books.open(root+r'\/data.xlsx',read_only=False)\nsht=wb.sheets('Sheet1')\ndata=sht.range('B2:C101').value\napp.kill()\n\nfrom comtypes.client import CreateObject\napp2=CreateObject(\"Excel.Application\")\napp2.Visible=True\nwb2=app2.Workbooks.Open(root+r'\/data.xlsx')\nsht2=wb2.Sheets('Sheet1')\n\nshp=sht2.Shapes.AddChart2()\nshp.Left=20\ncht=shp.Chart\ncht.ChartType=-4169\nax1=cht.Axes(1)\nax2=cht.Axes(2)\nax1.MinimumScale=0\nax1.MaximumScale=7\nax2.MinimumScale=0\nax2.MaximumScale=0.35\n\nset_style(cht)\n\ncht.SeriesCollection().NewSeries()\n\ncount1=count2=count3=count4=count5=count6=0\nd1=&#91;];d2=&#91;];d3=&#91;];d4=&#91;];d5=&#91;];d6=&#91;]\nfor i in range(100):\n    if data&#91;i]&#91;1]==1:\n        count1+=1\n        d1.append(data&#91;i]&#91;0])\n    elif data&#91;i]&#91;1]==2:\n        count2+=1\n        d2.append(data&#91;i]&#91;0])\n    elif data&#91;i]&#91;1]==3:\n        count3+=1\n        d3.append(data&#91;i]&#91;0])\n    elif data&#91;i]&#91;1]==4:\n        count4+=1\n        d4.append(data&#91;i]&#91;0])\n    elif data&#91;i]&#91;1]==5:\n        count5+=1\n        d5.append(data&#91;i]&#91;0])\n    elif data&#91;i]&#91;1]==6:\n        count6+=1\n        d6.append(data&#91;i]&#91;0])\n\ndraw_bar(cht,d1,count1,1,76,200,132,0.5,False)\ndraw_bar(cht,d2,count2,2,76,200,132,0.5,False)\ndraw_bar(cht,d3,count3,3,76,200,132,0.5,False)\ndraw_bar(cht,d4,count4,4,76,200,132,0.5,False)\ndraw_bar(cht,d5,count5,5,76,200,132,0.5,False)\ndraw_bar(cht,d6,count6,6,76,200,132,0.5,False)\n    \ndraw_rnd_scatter(cht,1,d1,count1,0.5,192,0,0)\ndraw_rnd_scatter(cht,2,d2,count2,0.5,255,192,0)\ndraw_rnd_scatter(cht,3,d3,count3,0.5,146,208,80)\ndraw_rnd_scatter(cht,4,d4,count4,0.5,0,176,80)\ndraw_rnd_scatter(cht,5,d5,count5,0.5,0,176,240)\ndraw_rnd_scatter(cht,6,d6,count6,0.5,0,112,192)\n\n#wb2.Save()\n#os.system('taskkill \/f \/im EXCEL.EXE')<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"880\" height=\"756\" src=\"https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-13.jpg\" alt=\"\" class=\"wp-image-1473\" srcset=\"https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-13.jpg 880w, https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-13-300x258.jpg 300w, https:\/\/xlwings.net\/blog\/wp-content\/uploads\/2026\/05\/3-13-768x660.jpg 768w\" sizes=\"auto, (max-width: 880px) 100vw, 880px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Method<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[],"class_list":["post-612","post","type-post","status-publish","format-standard","hentry","category-xlwings-advanced-chart"],"_links":{"self":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/comments?post=612"}],"version-history":[{"count":2,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/612\/revisions"}],"predecessor-version":[{"id":1474,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/posts\/612\/revisions\/1474"}],"wp:attachment":[{"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/media?parent=612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/categories?post=612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlwings.net\/blog\/wp-json\/wp\/v2\/tags?post=612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}