十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python数据可视化进阶:matplotlib画出专业图表的8个实战技巧

Python数据可视化进阶:matplotlib画出专业图表的8个实战技巧 文章目录环境信息前言matplotlib能画图但离专业还差这8个技巧技巧一中文字体 负号90%的人第一张图就卡在这技巧二双Y轴让两个不同量纲的数据同框对比技巧三子图布局tight_layout 是必须的技巧四语义化配色别用默认蓝橙技巧五注释标注用 annotate 点出重点技巧六高清导出bbox_inchestight 合理 dpi技巧七图例优化位置和列数技巧八组合图柱状图叠加折线总结环境信息项目版本/说明Python3.10matplotlib3.7numpy1.24pandas2.0示例数据香港差饷署租金指数 / 2021人口普查 / 环保署AQHI前言matplotlib能画图但离专业还差这8个技巧过去两周我写了一系列香港数据分析的文章——租金指数、人口普查、空气质量、MPF基金。每一篇的配图都是 matplotlib 画的。画了十几张图之后我回头翻看发现了一个扎心的事实前几张图和后几张图完全不是一个档次。前几张图是典型的教程图——默认配色、默认字体、挤在一起的标签、导出后模糊。后几张图开始有讲究了——语义化配色、清晰的注释、合适的子图布局、高清导出。差别不在会不会用 matplotlib而在那8个你只能在真实项目里踩坑才知道的技巧。这篇文章把这8个技巧整理出来每个都配一段可以直接复用的代码。收藏提示①这8个技巧是我画了十几张香港数据图之后总结的实战经验。前4个是让图能看后4个是让图专业。建议先收藏出图时对着改。技巧一中文字体 负号90%的人第一张图就卡在这importmatplotlibimportmatplotlib.pyplotaspltimportmatplotlib.font_managerasfm# 最关键的两行——不设置中文全是方框负号变成方块plt.rcParams[font.sans-serif][PingFang SC,Arial Unicode MS,SimHei,DejaVu Sans]plt.rcParams[axes.unicode_minus]False# 解决负号显示问题# macOS/Linux/Windows 字体不同用这段自动探测cjk_candidates[PingFang SC,Arial Unicode MS,Heiti TC,SimHei,Microsoft YaHei]available{f.nameforfinfm.fontManager.ttflist}chosennext((fforfincjk_candidatesiffinavailable),DejaVu Sans)plt.rcParams[font.sans-serif][chosen,DejaVu Sans]踩坑记录我在服务器无中文字体上跑图font.sans-serif里写死了PingFang SC结果中文全变方框。因为服务器是 Linux没有苹果字体。所以字体列表一定要带 fallback——最后加一个DejaVu Sans兜底至少英文不会崩。技巧二双Y轴让两个不同量纲的数据同框对比香港租金数据里租金指数和同比涨幅是两个完全不同的量纲一个100一个是百分比。硬塞一个坐标轴涨幅那条线会贴地看不见。用双Y轴importnumpyasnp fig,ax1plt.subplots(figsize(11,5))# 左轴租金指数量纲大xnp.arange(12)rental_idxnp.array([198,199,200,201,202,203,204,206,208,209,210,211])ax1.plot(x,rental_idx,o-,color#E74C3C,lw2.5,markersize6,label租金指数)ax1.set_xlabel(月份,fontsize11)ax1.set_ylabel(租金指数,fontsize11,color#E74C3C)ax1.tick_params(axisy,labelcolor#E74C3C)# 右轴同比涨幅百分比ax2ax1.twinx()yoynp.array([4.2,4.5,4.8,5.1,5.3,5.6,5.8,5.9,6.1,6.0,5.9,5.8])ax2.plot(x,yoy,s--,color#3498DB,lw2,markersize6,label同比涨幅(%))ax2.set_ylabel(同比涨幅 (%),fontsize11,color#3498DB)ax2.tick_params(axisy,labelcolor#3498DB)# 合并图例lines1,labels1ax1.get_legend_handles_labels()lines2,labels2ax2.get_legend_handles_labels()ax1.legend(lines1lines2,labels1labels2,fontsize10,locupper left)ax1.set_title(香港租金指数与同比涨幅双Y轴,fontsize13,fontweightbold)ax1.grid(alpha0.3)fig.tight_layout()关键点两个坐标轴的刻度颜色要和曲线颜色一致tick_params(labelcolor...)否则读者分不清哪条线对哪个轴。技巧三子图布局tight_layout是必须的多图并排时标签重叠是常态。plt.tight_layout()或constrained_layoutTrue是解决之道fig,axesplt.subplots(2,2,figsize(12,8),constrained_layoutTrue)# 四象限港岛/九龙/新界 × 租金/人口data{(0,0):(港岛租金,#E74C3C,[180,185,190,195]),(0,1):(九龙租金,#F39C12,[170,172,175,178]),(1,0):(新界租金,#27AE60,[160,162,165,168]),(1,1):(全港平均,#3498DB,[175,178,181,184]),}for(i,j),(title,color,vals)indata.items():axaxes[i,j]ax.plot(vals,o-,colorcolor,lw2,markersize5)ax.set_title(title,fontsize11)ax.grid(alpha0.2)fig.suptitle(香港三大区域租金指数对比,fontsize14,fontweightbold,y1.02)# constrained_layout 已处理间距无需再 tight_layout收藏提示②constrained_layoutTrue比tight_layout()更省心——它会自动处理 suptitle 和子图标签的重叠。如果你总是被tight_layout的 warning 烦到试试前者。技巧四语义化配色别用默认蓝橙matplotlib 默认的 tab10 配色蓝橙混在一起毫无语义。专业图表用颜色表达含义# ❌ 错误默认配色颜色无意义# ✅ 正确颜色 语义# 红跌/警示绿涨/安全蓝中性橙预警SEMANTIC_COLORS{上升:#27AE60,# 绿 涨下降:#E74C3C,# 红 跌持平:#95A5A6,# 灰 平稳预警:#F39C12,# 橙 注意信息:#3498DB,# 蓝 中性信息}# 人口老龄化示例超过20%用警示橙/红低于18%用绿elderly{中西区:17.2,东区:21.5,观塘:19.5,西贡:14.2}colors[SEMANTIC_COLORS[预警]ifv20elseSEMANTIC_COLORS[上升]ifv18elseSEMANTIC_COLORS[信息]forvinelderly.values()]fig,axplt.subplots(figsize(8,4.5))barsax.bar(elderly.keys(),elderly.values(),colorcolors,edgecolorwhite,lw1.5)ax.axhline(y18,color#7F8C8D,linestyle--,alpha0.5,label警戒线 18%)ax.set_ylabel(65岁以上人口占比 (%),fontsize11)ax.set_title(各区老龄化率颜色语义绿安全/橙预警,fontsize12,fontweightbold)ax.legend(fontsize9)ax.grid(alpha0.2)fig.tight_layout()这个技巧我在0812的人口普查文章里就用过——老龄化超过20%的区标橙低于18%的标绿读者一眼就能看出哪个区老了。技巧五注释标注用annotate点出重点图的价值在于传达洞察而洞察需要被指出来。annotate是点出重点的核心工具fig,axplt.subplots(figsize(11,5))# 空气质量数据台风过境前后的PM2.5daysnp.arange(14)pm25np.array([45,48,52,58,62,35,28,22,20,24,30,38,42,40])ax.plot(days,pm25,o-,color#3498DB,lw2.5,markersize7)# 标注峰值台风前污染累积peak_idxnp.argmax(pm25)ax.annotate(台风前污染累积峰值\nPM2.5 62 μg/m³,xy(peak_idx,pm25[peak_idx]),xytext(peak_idx2,pm25[peak_idx]8),fontsize10,color#C0392B,fontweightbold,arrowpropsdict(arrowstyle-,color#C0392B,lw2),bboxdict(boxstyleround,fc#FDEDEC,ec#E74C3C,alpha0.9))# 标注低谷台风过境净化trough_idxnp.argmin(pm25)ax.annotate(台风过境后空气质量骤降,xy(trough_idx,pm25[trough_idx]),xytext(trough_idx3,pm25[trough_idx]-12),fontsize10,color#1E8449,fontweightbold,arrowpropsdict(arrowstyle-,color#1E8449,lw2),bboxdict(boxstyleround,fc#E8F8F5,ec#27AE60,alpha0.9))ax.set_xlabel(天数,fontsize11)ax.set_ylabel(PM2.5 (μg/m³),fontsize11)ax.set_title(台风过境前后的空气质量变化,fontsize13,fontweightbold)ax.grid(alpha0.3)fig.tight_layout()bbox参数加个圆角边框注释立刻从贴在图上的一行字变成一个醒目的说明标签。技巧六高清导出bbox_inchestight 合理 dpi# ❌ 错误默认保存标签可能被裁切且分辨率低# fig.savefig(chart.png)# ✅ 正确裁剪白边 高清fig.savefig(chart.png,dpi150,# 网页用150足够印刷用300bbox_inchestight,# 自动裁掉多余白边防止标签被切facecolorwhite# 强制白底防止透明背景在深色主题下看不清)踩坑记录我最早保存的图坐标轴标签经常被切掉一半。原因是默认savefig不裁边而tight_layout只对show()生效。bbox_inchestight才是导出时裁边的正确参数——两者容易混淆但只有后者影响导出。技巧七图例优化位置和列数图例放错位置会挡数据放对位置是点睛# 图例位置的选择逻辑# - 数据集中在右上 → 图例放左上 (upper left)# - 数据集中在左上 → 图例放右上 (upper right)# - 线条多 → 用 ncol 分列避免图例过长ax.legend(fontsize10,locupper left,# 避开数据区ncol2,# 6个图例分成2列不占整行framealpha0.8,# 半透明边框不遮数据edgecolor#D5D8DC# 浅灰边框比默认黑边柔和)技巧八组合图柱状图叠加折线这是最实用的进阶图表——柱状图表达量折线图表达趋势fig,axplt.subplots(figsize(11,5.5))# 柱状图月度成交量months[1月,2月,3月,4月,5月,6月,7月,8月]volume[120,95,140,155,130,168,150,145]barsax.bar(months,volume,color#AED6F1,edgecolor#3498DB,lw1.5,label成交量)# 折线图均价叠加在柱状图上avg_price[520,510,535,548,540,560,555,552]ax2ax.twinx()ax2.plot(months,avg_price,o-,color#E74C3C,lw3,markersize8,label均价)# 在柱子上标注数值forbar,vinzip(bars,volume):ax.text(bar.get_x()bar.get_width()/2,v3,str(v),hacenter,fontsize9,fontweightbold,color#2C3E50)ax.set_ylabel(成交量,fontsize11,color#3498DB)ax2.set_ylabel(均价 (万港币),fontsize11,color#E74C3C)ax.set_title(香港某区楼市量价组合图,fontsize13,fontweightbold)# 双图例h1,l1ax.get_legend_handles_labels()h2,l2ax2.get_legend_handles_labels()ax.legend(h1h2,l1l2,fontsize10,locupper left)ax.grid(alpha0.3)fig.tight_layout()收藏提示③这8个技巧按出图流程组织——先设置字体技巧一再选图表类型双Y轴/子图/组合图然后配色四、标注重点五、优化图例七最后高清导出六。出图时按这个顺序过一遍图的质量能上一个台阶。总结matplotlib 是 Python 数据科学栈里最入门易、精通难的库。入门只要plt.plot()但画出能放进报告/博客/论文的专业图靠的是这8个在真实项目里踩出来的技巧字体 负号——不设置第一张图就废双Y轴——量纲不同就分开刻度颜色对齐曲线子图布局——constrained_layout省心语义化配色——颜色要表达含义不是随机注释标注——洞察要指出来bbox加边框高清导出——bbox_inchestight 合理 dpi图例优化——位置避开数据多列不占行组合图——柱状表达量折线表达趋势过去两周我的香港数据系列租金、人口、空气质量所有配图都是这套方法画出来的。现在把这些技巧单独整理出来是因为我发现——会调用 matplotlib和能画出专业图之间差的恰恰是这8个细节。本文为 Python 数据可视化技巧分享。示例数据基于香港差饷署租金指数、2021人口普查、环保署AQHI均为公开数据。8个技巧均在作者过往文章的实际配图中验证。
返回列表