今天咱不聊鸡汤、不讲情怀,直接开整!带你沉浸式体验 Python 可视化神器——Matplotlib的20种最常见图表玩法。
不管你是数据分析,机器学习,还是做周报、写PPT,只要掌握了这些图形,绝对是质的飞跃!
接下来,准备好你的 IDE,我们一个个上手敲起来!
注:要想Matplotlib支持中文!代码跑之前记得加上 这一行解决中文乱码问题:
pipinstallmatplotlib如何你还没有安装matplotlib请打开你的终端(Terminal)或者命令行(cmd),直接敲:
pipinstallmatplotlib回车,喝口水,等一会儿,它自己就装好了。
常用于趋势变化,比如气温、股价、KPI变化啥的。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文x=[1,2,3,4,5]y=[3,5,7,6,9]plt.plot(x,y,marker='o')plt.title('每日访问量变化')plt.xlabel('日期')plt.ylabel('访问量')plt.grid(True)plt.show()
横着比数据,适合分类比较。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文categories=['小红','小明','小刚','小美']scores=[90,80,75,88]plt.bar(categories,scores,color='skyblue')plt.title('四人考试成绩对比')plt.show()
适合看数据分布,比如工资分布、身高、体重这些。
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文data=np.random.normal(170,10,200)plt.hist(data,bins=20,color='orange',edgecolor='black')plt.title('身高分布图')plt.xlabel('身高')plt.ylabel('人数')plt.show()
两个变量之间的关系,看是否相关。
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文x=np.random.rand(100)y=x+np.random.normal(0,0.1,100)plt.scatter(x,y)plt.title('学习时间 vs 成绩')plt.xlabel('学习时间')plt.ylabel('成绩')plt.show()
占比图!让老板看谁吃的预算多
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文labels=['广告','运营','人力','技术']sizes=[30,20,10,40]plt.pie(sizes,labels=labels,autopct='%1.1f%%',startangle=140)plt.title('部门预算占比')plt.axis('equal')plt.show()
比折线图多了一点“填充感”,也更直观。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文x=range(1,6)y=[1,3,4,8,12]plt.fill_between(x,y,color="lightgreen")plt.plot(x,y,color="green")plt.title('用户增长趋势')plt.show()
统计分析必备,帮你看离群值、上下四分位这些。
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文data=[np.random.normal(50,std,100)forstdin(5,10,20)]plt.boxplot(data,patch_artist=True)plt.title('三组数据分布对比')plt.show()
用颜色来表现数值大小,强烈推荐结合seaborn!
importmatplotlib.pyplotaspltimportnumpyasnpimportseabornassnsplt.rcParams['font.family']='SimHei'# 黑体支持中文data=np.random.rand(6,6)sns.heatmap(data,annot=True)plt.title('热力图示例')plt.show()
多维指标一图展示,简历必备,别说我没告诉你
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文labels=['沟通','编码','学习','抗压','责任心']stats=[8,9,7,6,8]angles=np.linspace(0,2*np.pi,len(labels),endpoint=False).tolist()stats+=stats[:1]angles+=angles[:1]fig,ax=plt.subplots(subplot_kw={'polar':True})ax.plot(angles,stats,'o-',linewidth=2)ax.fill(angles,stats,alpha=0.25)ax.set_thetagrids(np.degrees(angles[:-1]),labels)plt.title('我的技能雷达图')plt.show()
散点+极坐标,视觉冲击感超强。
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文r=np.linspace(0,1,100)theta=2*np.pi*rplt.polar(theta,r)plt.title('极坐标示例')plt.show()
两个Y轴,两个变量共用一个X轴,超实用。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文# 数据months=['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']sales=[120,150,200,180,220,260,240,300,320,310,400,500]new_users=[3500,3800,4200,4000,5000,5200,4800,6000,6300,6200,7500,8000]fig,ax1=plt.subplots(figsize=(10,6))# 左轴:销售额color='tab:blue'ax1.set_xlabel('月份')ax1.set_ylabel('销售额(万元)',color=color)ax1.plot(months,sales,color=color,marker='o',label='销售额')ax1.tick_params(axis='y',labelcolor=color)# 右轴:新注册用户ax2=ax1.twinx()color='tab:red'ax2.set_ylabel('新注册用户(人)',color=color)ax2.plot(months,new_users,color=color,marker='s',linestyle='--',label='新注册用户')ax2.tick_params(axis='y',labelcolor=color)plt.title('某电商平台2024年月度销售额与新注册用户')ax1.grid(True)plt.show()
增强折线图表达力的小技巧!
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文# 折线数据months=['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']avg_price=[18500,18700,19000,18800,19200,19400,19500,19800,20000,20200,20500,21000]# 散点数据special_months=['3月','6月','8月','11月']special_price=[21000,22000,23000,25000]fig,ax=plt.subplots(figsize=(10,6))# 画折线图ax.plot(months,avg_price,color='blue',marker='o',label='平均房价(元/㎡)')# 画散点图ax.scatter(special_months,special_price,color='red',s=100,marker='*',label='特殊成交(元/㎡)')plt.title('2024年某小区月均房价及特殊成交记录')plt.xlabel('月份')plt.ylabel('价格(元/㎡)')plt.legend()plt.grid(True)plt.show()
适合描述“突变”的情况,比如电费、分段计价那种。
importmatplotlib.pyplotaspltfromdatetimeimportdatetimeimportmatplotlib.datesasmdatesplt.rcParams['font.family']='SimHei'# 黑体支持中文# 数据dates=['2023-10-01','2023-10-02','2023-10-03','2023-10-04','2023-10-05','2023-10-06','2023-10-07']temperatures=[22,23,20,19,18,20,21]# 转换日期格式dates=[datetime.strptime(d,'%Y-%m-%d')fordindates]# 创建图表plt.figure(figsize=(10,6))# 绘制阶梯图(post样式的阶梯变化)plt.step(dates,temperatures,where='post',# 阶梯在数据点后变化color='#E64A45',# 中国红配色linewidth=2.5,marker='o',# 添加数据点标记markersize=8,markerfacecolor='white',markeredgewidth=2,label='每日最高气温')# 添加标题和标签plt.title('北京市国庆期间气温变化(2024年10月1-7日)',fontsize=14,pad=20)plt.xlabel('日期',fontsize=12)plt.ylabel('温度 (°C)',fontsize=12)# 配置坐标轴plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))plt.gca().xaxis.set_major_locator(mdates.DayLocator())plt.xticks(rotation=30)plt.ylim(15,25)# 添加辅助元素plt.grid(axis='y',linestyle='--',alpha=0.7)plt.tight_layout()plt.legend(loc='upper left',frameon=False)plt.show()
视觉更舒服,直接用wedgeprops搞定。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文# 数据categories=['煤炭','石油','天然气','可再生能源\n(水电/风电/光伏)']percentages=[56.2,18.5,9.4,15.9]colors=['#6D8698',# 灰蓝(煤炭)'#BE7352',# 棕褐(石油)'#8FA6A2',# 青灰(天然气)'#8FB3B0'# 浅绿(可再生能源)]# 创建带中心洞的环形图fig,ax=plt.subplots(figsize=(8,8))wedges,texts,autotexts=ax.pie(percentages,wedgeprops={'width':0.5,# 环宽=半径的50%'edgecolor':'white',# 白色分割线'linewidth':1.5# 分割线粗细},colors=colors,startangle=90,# 起始角度(12点方向)autopct='%1.1f%%',# 百分比格式pctdistance=0.85# 百分比标签位置(0.85倍半径))# 设置百分比标签样式forautotextinautotexts:autotext.set_color('white')autotext.set_fontsize(10)autotext.set_weight('bold')# 添加中心标题ax.text(0,0,'XX国能源结构\n2024',ha='center',va='center',fontsize=16,fontweight='bold',color='#2F4F4F')# 添加图例(带透明度效果)legend=ax.legend(wedges,categories,title="能源类型",loc="center left",bbox_to_anchor=(1,0,0.5,1),frameon=False,labelspacing=1.2)legend.get_title().set_fontweight('bold')# 设置长宽比保证正圆形ax.axis('equal')plt.tight_layout()plt.show()
实验、分析场景常用。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文# 数据 (单位:万辆)quarters=['Q1','Q2','Q3','Q4']avg_sales=[158.6,173.2,204.6,227.4]# 季度平均销量std_dev=[8.2,9.5,11.3,13.1]# 各季度销量标准差# 创建带误差线的散点图plt.figure(figsize=(10,6))# 主绘图语句main_line=plt.errorbar(x=quarters,y=avg_sales,yerr=std_dev,# 误差线数据fmt='o-',# 点线组合markersize=10,markerfacecolor='#2E86C1',markeredgecolor='white',elinewidth=2,# 误差线粗细ecolor='#E74C3C',# 误差线颜色capsize=8,# 误差线顶端横杠长度linewidth=2.5,label='平均销量 ± 标准差')# 添加数据标签fori,(v,s)inenumerate(zip(avg_sales,std_dev)):plt.text(i,v+15,f'{v}±{s}',ha='center',fontsize=10,bbox=dict(facecolor='white',alpha=0.8))# 可视化优化plt.title('2024年中国新能源汽车季度销量误差分析',fontsize=14,pad=20)plt.ylabel('销量 (万辆)',labelpad=12)plt.ylim(120,260)plt.grid(axis='y',linestyle='--',alpha=0.6)# 添加图例leg=plt.legend(loc='upper left')leg.get_frame().set_linewidth(0.0)# 移除图例边框plt.tight_layout()plt.show()
展示函数值随二维变量变化的趋势。
importmatplotlib.pyplotaspltfrommatplotlibimportcmimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文plt.rcParams['axes.unicode_minus']=False# 解决负数乱码问题# 生成地形数据(模拟青海湖周边区域 20x20公里)x=np.linspace(-10,10,200)y=np.linspace(-8,12,200)X,Y=np.meshgrid(x,y)# 高程函数(包含湖盆与山脉特征)Z=3200+50*Y-40*X**2+30*np.sin(2*X)+45*np.exp(-(X**2+Y**2)/25)# 创建画布plt.figure(figsize=(12,8))# 绘制填充等高线cs=plt.contourf(X,Y,Z,levels=np.linspace(3100,3700,13),cmap=cm.gist_earth,alpha=0.85)# 绘制等高线c_lines=plt.contour(X,Y,Z,levels=np.linspace(3100,3700,13),colors='black',linewidths=0.6)# 添加标签plt.clabel(c_lines,inline=True,fontsize=8,fmt='%d m')# 添加高程标注# 添加色标cbar=plt.colorbar(cs)cbar.set_label('高程(米)',rotation=270,labelpad=20)# 设置地形图元素plt.title('青海湖周边地形等高线模拟图',pad=20,fontsize=14)plt.xlabel('东西向距离 (公里)')plt.ylabel('南北向距离 (公里)')plt.grid(linestyle=':',alpha=0.5)# 标注特征区域plt.text(-8,10,'日月山脉',ha='left',va='center',fontsize=9,color='#8B0000')plt.annotate('青海湖水域',xy=(-1,3),xytext=(-9,5),arrowprops=dict(arrowstyle="->",color='navy'),fontsize=9,color='#00008B')plt.tight_layout()plt.show()
你没看错,Matplotlib也能画3D!
importmatplotlib.pyplotaspltfrommatplotlibimportcmimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文 plt.rcParams['axes.unicode_minus'] = False # 解决负数乱码问题 # 生成真实地形数据(模拟黄石公园44.5°N, 110.5°W区域) x = np.linspace(-5, 5, 150) y = np.linspace(-5, 5, 150) X, Y = np.meshgrid(x, y) # 高程函数(包含火山口与地热区特征) Z = 2400 + 50*np.exp(-0.3*(X**2 + Y**2)) - 200*np.exp(-0.8*((X+1)**2 + (Y-0.5)**2)) Z += 30*np.sin(2*X) * np.cos(3*Y) # 创建3D画布 fig = plt.figure(figsize=(14, 10)) ax = fig.add_subplot(111, projection='3d') # 绘制曲面 surf = ax.plot_surface(X, Y, Z, cmap=cm.terrain, # 地形专用色标 rstride=2, # 行采样步长 cstride=2, # 列采样步长 alpha=0.95, antialiased=True, linewidth=0.2, edgecolor='#333333') # 添加色标 cbar = fig.colorbar(surf, shrink=0.6, aspect=30) cbar.set_label('高程 (米)', rotation=270, labelpad=25) # 设置观测角度 ax.view_init(elev=35, azim=300) # 35度俯角,300度方位角 # 添加标注 ax.set_xlabel('东西向 (公里)', labelpad=12) ax.set_ylabel('南北向 (公里)', labelpad=12) ax.set_zlabel('高程', labelpad=12) ax.set_title('某国家公园地热区3D地形模型', y=0.98, fontsize=14) # 添加地形特征标注 ax.text(-4, -4, 2600, '▲ 火山口', color='#8B0000', fontsize=9) ax.text(1.5, 0.8, 2250, '地热喷泉区', color='#2F4F4F', fontsize=9) # 优化显示效果 ax.xaxis.pane.fill = False ax.yaxis.pane.fill = False ax.zaxis.pane.fill = False ax.xaxis._axinfo["grid"].update({"linewidth":0.3, "color" : "#666666"}) ax.yaxis._axinfo["grid"].update({"linewidth":0.3, "color" : "#666666"}) ax.zaxis._axinfo["grid"].update({"linewidth":0.3, "color" : "#666666"}) plt.tight_layout() pltimport matplotlib.pyplot as pltfrommatplotlibimportcmimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文plt.rcParams['axes.unicode_minus']=False# 解决负数乱码问题# 生成真实地形数据(模拟黄石公园44.5°N, 110.5°W区域)x=np.linspace(-5,5,150)y=np.linspace(-5,5,150)X,Y=np.meshgrid(x,y)# 高程函数(包含火山口与地热区特征)Z=2400+50*np.exp(-0.3*(X**2+Y**2))-200*np.exp(-0.8*((X+1)**2+(Y-0.5)**2))Z+=30*np.sin(2*X)*np.cos(3*Y)# 创建3D画布fig=plt.figure(figsize=(14,10))ax=fig.add_subplot(111,projection='3d')# 绘制曲面surf=ax.plot_surface(X,Y,Z,cmap=cm.terrain,# 地形专用色标rstride=2,# 行采样步长cstride=2,# 列采样步长alpha=0.95,antialiased=True,linewidth=0.2,edgecolor='#333333')# 添加色标cbar=fig.colorbar(surf,shrink=0.6,aspect=30)cbar.set_label('高程 (米)',rotation=270,labelpad=25)# 设置观测角度ax.view_init(elev=35,azim=300)# 35度俯角,300度方位角# 添加标注ax.set_xlabel('东西向 (公里)',labelpad=12)ax.set_ylabel('南北向 (公里)',labelpad=12)ax.set_zlabel('高程',labelpad=12)ax.set_title('某国家公园地热区3D地形模型',y=0.98,fontsize=14)# 添加地形特征标注ax.text(-4,-4,2600,'▲ 火山口',color='#8B0000',fontsize=9)ax.text(1.5,0.8,2250,'地热喷泉区',color='#2F4F4F',fontsize=9)# 优化显示效果ax.xaxis.pane.fill=Falseax.yaxis.pane.fill=Falseax.zaxis.pane.fill=Falseax.xaxis._axinfo["grid"].update({"linewidth":0.3,"color":"#666666"})ax.yaxis._axinfo["grid"].update({"linewidth":0.3,"color":"#666666"})ax.zaxis._axinfo["grid"].update({"linewidth":0.3,"color":"#666666"})plt.tight_layout()plt.show()
其实是散点图加强版,用大小表示变量大小。
importmatplotlib.pyplotaspltimportnumpyasnpplt.rcParams['font.family']='SimHei'# 黑体支持中文plt.rcParams['axes.unicode_minus']=False# 解决负数乱码问题# 各省份数据(GDP单位:万亿元,人口单位:千万人)provinces=['广东','江苏','山东','浙江','河南','四川','湖北','福建','湖南','安徽']gdp=[12.91,12.29,8.74,7.77,6.13,5.67,5.37,5.31,4.87,4.50]population=[126.6,85.1,101.6,65.4,98.7,83.7,58.3,41.8,66.4,61.3]per_capita_gdp=[10.2,14.4,8.6,11.9,6.2,6.8,9.2,12.7,7.3,7.3]# 单位:万元/人# 创建画布plt.figure(figsize=(14,8))# 绘制气泡图scatter=plt.scatter(x=gdp,y=population,s=np.array(per_capita_gdp)*400,# 气泡大小缩放c=np.arange(len(provinces)),# 颜色映射cmap='tab20',alpha=0.8,edgecolors='white',linewidths=0.8)# 设置坐标轴plt.title('xxxx主要省份经济数据气泡图',fontsize=14,pad=20)plt.xlabel('GDP(万亿元)',labelpad=12)plt.ylabel('人口(千万人)',labelpad=12)plt.grid(linestyle=':',alpha=0.6)# 设置坐标范围plt.xlim(3,14)plt.ylim(30,130)plt.tight_layout()plt.show()
展示“转化率”的神器。
importmatplotlib.pyplotaspltplt.rcParams['font.family']='SimHei'# 黑体支持中文plt.rcParams['axes.unicode_minus']=False# 解决负数乱码问题labels=['访问','注册','激活','付费']values=[1000,800,400,100]plt.barh(labels,values)plt.title('用户转化漏斗')plt.show()
别说静态图无聊,Matplotlib也能动起来!
importmatplotlib.pyplotaspltimportnumpyasnpfrommatplotlibimportanimationplt.rcParams['font.family']='SimHei'# 黑体支持中文plt.rcParams['axes.unicode_minus']=False# 解决负数乱码问题fig,ax=plt.subplots()x=np.linspace(0,2*np.pi,128)line,=ax.plot(x,np.sin(x))defupdate(i):line.set_ydata(np.sin(x+i/10.0))returnline,ani=animation.FuncAnimation(fig,update,frames=100,interval=50)plt.title('动态正弦波')plt.show()
原文链接:https://zhuanlan.zhihu.com/p/1906641913332895760
版权声明