Python生态绘图类库:Folium、PlotNine、LeafMap、PyGal、CartoPy、floWeaver

Python生态绘图类库:Folium、PlotNine、LeafMap、PyGal、CartoPy、floWeaver

继Python生态绘图类库:Plotly、Altair、bqplot、plotlet之后,本文继续汇总Python生态下,特定领域下的绘图类库。

Folium

项目主页,地图画图工具开源(GitHub,7.4K Star,2.3K Fork)类库,基于Leaflet.js,可在Jupyter Notebook里画出可缩放、可拖拽、带标记点的交互式地图。

适用场景

场景说明
数据可视化报告在Jupyter里展示地理数据分布
门店/网点分布图批量打点,直观看到覆盖范围
路线规划展示把GPS轨迹画出来
热力图分析如人口密度、事故高发区

实战

基于pip安装:pip install folium

示例:

importfolium# 创建地图,定位到北京m=folium.Map(location=[39.9042,116.4074],zoom_start=12)# 加标记点folium.Marker([39.9042,116.4074],popup="天安门",icon=folium.Icon(color="red",icon="info-sign")).add_to(m)# 保存HTML文件m.save("map.html")# 在Jupyter里直接显示m

批量打点:

importfoliumfromfolium.pluginsimportHeatMapimportpandasaspd# 门店数据stores=pd.DataFrame({'name':['店A','店B','店C'],'lat':[39.90,39.92,39.88],'lng':[116.40,116.42,116.38]})m=folium.Map(location=[39.90,116.40],zoom_start=13)for_,rowinstores.iterrows():folium.Marker([row['lat'],row['lng']],popup=row['name']).add_to(m)# 用经纬度数据生成热力图heat_data=[[row['lat'],row['lng']]for_,rowinstores.iterrows()]HeatMap(heat_data).add_to(m)m

效果图

画区域、画路径

# 画折线folium.PolyLine(locations=[(39.90,116.40),(39.92,116.42),(39.88,116.38)],color='blue',weight=5).add_to(m)# 画圆,如覆盖范围folium.Circle(location=[39.90,116.40],radius=1000,# 米color='red',fill=True).add_to(m)

展示效果

PlotNine

官网,图形语法绘图开源(GitHub,4.8K Star,254 Fork)库,把ggplot2风格的Grammar of Graphics带到Python,强调数据、映射、几何对象、坐标和分面等概念,比先画线再调样式的过程更声明式,官方文档。

适合统计探索、分组对比、教学材料、希望用一致语法组织复杂统计图、从R或ggplot2迁移来的团队,以及需要统一图形语法的分析脚本。

不适合极复杂的交互式Web图表,或需要直接操控Matplotlib底层每个Artist的精细场景。

特点

  • 语法清晰:用aes、geom、facet、coord组合图表,表达意图很明确
  • 适合统计图:分面、颜色映射、几何层叠很自然
  • 承接Pandas:DataFrame字段直接进入映射,分析脚本里衔接顺。

实战

基于pip安装:pip install plotnine

示例:

importpandasaspdfromplotnineimportaes,coord_flip,facet_wrap,geom_point,geom_col,ggplot,stat_smooth,theme_xkcd,theme_tufte,theme_minimalfromplotnine.dataimportmtcars(ggplot(mtcars,aes("wt","mpg",color="factor(gear)"))# 调用mtcars数据集,以车重wt与每加仑行驶英里数mpg为坐标,颜色受gear影响+geom_point())

绘制效果图

(ggplot(mtcars,aes("wt","mpg",color="factor(gear)"))+geom_point()+stat_smooth(method="lm")# 绘制线性拟合曲线)

效果图(需要等十几秒钟):

(ggplot(mtcars,aes("wt","mpg",color="factor(gear)"))+geom_point()+stat_smooth(method="lm")+facet_wrap("gear")# 按gear进行分组,以多面展示数据)

效果图

(ggplot(mtcars,aes("wt","mpg",color="factor(gear)"))+geom_point()+stat_smooth(method="lm")+facet_wrap("gear")+theme_xkcd()# 绘制手绘风格主题# + theme_tufte() # Tufte 风格主题# + theme_minimal() # 系统默认# + theme_bw() # 系统默认)

可能会输出字体不存在,渲染没有什么较大影响

findfont: Font family 'xkcd' not found. findfont: Font family 'Humor Sans' not found.

不想看到警告信息,添加两行代码:

importlogging logging.getLogger('matplotlib.font_manager').setLevel(logging.ERROR)

渲染效果:

也可从xkcd-font官网下载xkcd.ttf字体文件。

更多示例:

df=pd.DataFrame({"x":[1,2,3],"y":[2,5,3]})p=ggplot(df,aes("x","y"))+geom_point()fig=p.draw(show=False)print("layers:",len(p.layers))print("axes:",len(fig.axes))df=pd.DataFrame({"team":["A","B","C"],"score":[7,4,9]})p=ggplot(df,aes("team","score"))+geom_col(fill="#4c78a8")+coord_flip()fig=p.draw(show=False)print("layers:",len(p.layers))print("coord:",type(p.coordinates).__name__)print("axes:",len(fig.axes))df=pd.DataFrame({"x":[1,2,1,2],"y":[3,5,2,7],"team":["A","A","B","B"]})p=ggplot(df,aes("x","y",color="team"))+geom_point(size=3)+facet_wrap("team")fig=p.draw(show=False)print("facets:",type(p.facet).__name__)print("panels:",len(fig.axes))

解读:把不同统计视角拆成geomfacet,比在一段imperative代码里不断改axes更容易维护。

注意事项:

  1. 固定输入字段、数据量范围和缺失值策略
  2. 明确图表是静态导出、Notebook交互、桌面GUI还是Web嵌入
  3. 在目标运行环境里做一次渲染或导出验证

LeafMap

官网,基于folium,开源(GitHub,3.8K Star,469 Fork)零代码地理数据分析与交互式绘图包。

能力

  • 超多后端随意切换:可切换到foliumipyleafletkepler.glpydeckbokeh等不同后端,根据场景选最顺手的工具
  • 交互式绘图工具:内置图形界面,很多操作(如加载数据、画图)不用写代码,在Jupyter里点点鼠标就能完成
  • 分析能力强大:集成WhiteboxTools分析工具库,可直接在地图上进行水文分析、地形分析、LiDAR数据处理等
  • 对新手和专家都友好:初学者能快速上手出图,专业用户也能用它处理复杂的空间数据和分析任务

实战

基于pip安装:pip install leafmap

示例:

PyGal

官网,SVG 图表生成开源(GitHub,2.8K Star,419 Fork)。创建图表对象、设置标签、添加series、渲染为SVG。

相比大型交互式可视化框架,更适合在文档、邮件图表、静态页面和报告里产出可缩放矢量图、需要SVG文件的自动化脚本,以及需要轻量、可嵌入、无需复杂前端依赖时。适合在构建流程里生成、缓存、嵌入,而不是依赖运行时再画。

不适合高度复杂的交互式分析平台,或需要海量数据点实时重绘的科学计算界面。

特点

  • SVG输出:图表天然可缩放,适合文档和静态页面
  • API简洁:Bar、Line、Radar等图表对象直接添加数据即可
  • 依赖轻:不用完整前端框架,也能生成可用图表资产

实战

基于pip安装:pip install pygal

示例

importpygal chart=pygal.Bar()chart.title="sales"chart.x_labels=["Jan","Feb","Mar"]chart.add("sales",[120,160,90])svg=chart.render()print("series:",len(chart.raw_series))print("svg bytes:",len(svg))chart=pygal.Line(interpolate="cubic")chart.add("A",[1,3,2,5])chart.add("B",[2,2,4,3])names=[meta["title"]fordata,metainchart.raw_series]svg=chart.render()print("series names:",names)print("series count:",len(chart.raw_series))print("svg bytes:",len(svg))chart=pygal.Radar()chart.x_labels=["speed","quality","cost"]chart.add("plan A",[8,7,5])chart.add("plan B",[6,9,7])svg=chart.render(is_unicode=True)print("radar labels:",list(chart.x_labels))print("has svg:",svg.lstrip().startswith("<?xml"))

CartoPy

面向地图绘制和地理投影的开源(GitHub,1.6K Star,396 Fork)库,常和Matplotlib、NumPy、GeoPandas一起使用。把经纬度坐标、投影坐标、地图要素和坐标轴变换放进同一套模型里管理。适合气象图、海洋航线、遥感辅助图、区域统计地图等场景下的可视化,官方文档。

特点

  • 投影清楚:CRS对象负责坐标系统和变换,适合在图上混合经纬度、墨卡托等坐标
  • 要素可控:Natural Earth要素可按类别和比例尺组织,便于控制海岸线、陆地等素材
  • 生态兼容:和Matplotlib配合紧密,适合把科学计算结果落到地图视图里

不适合只想快速在网页里拖动地图的场景;这类需求通常Leaflet、Mapbox或Folium更合适。

实战

基于pip安装:pip install cartopy

示例:

importcartopy.crsasccrsimportcartopy.featureascfeatureimportnumpyasnp src=ccrs.PlateCarree()dst=ccrs.Mercator()pts=dst.transform_points(src,np.array([0,120]),np.array([0,30]))fmt=lambdarow:[float(round(v,2))forvinrow[:2]]print("threshold:",round(src.threshold,3))print("points:",pts.shape)print("x0/y0:",fmt(pts[0]))print("x1/y1:",fmt(pts[1]))land=cfeature.NaturalEarthFeature("physical","land","110m")print("feature:",land.name)print("category:",land.category)print("scale:",land.scale)

解读:

  • 把经纬度点转换到Web/墨卡托类坐标,验证数据坐标能进入目标投影
  • 定义Natural Earth地图要素,后续可交给Matplotlib轴对象渲染

注意事项:

  1. 固定Python、核心库和系统依赖版本,避免环境漂移
  2. 用小样本覆盖输入边界、空值、异常值和坐标/数组维度
  3. 把外部服务、投影数据或编译依赖写进部署文档

floWeaver

开源(GitHub,464 Star,89 Fork)流数据可视化,可将类似于“源-目标-数值”这种表单数据,变成比例精准、配色高级的桑基图,官方文档。

组件:

  • floWeaver:负责逻辑层
  • ipysankeywidget:负责在Jupyter里渲染图表

用ProcessGroup定义聚合类别,用Waypoint标记节点,SankeyDefinition负责布局,Weave负责数据映射。

实战

基于pip安装:pip install floweaver

示例:

fromfloweaverimportSankeyDefinition,WeavefromfloweaverimportProcessGroup,Waypointimportpandasaspd group_elect=ProcessGroup('电子产品')group_home=ProcessGroup('家居生活')group_cloth=ProcessGroup('服饰美妆')w_elect=Waypoint(group_elect,title='电子')w_home=Waypoint(group_home,title='家居')w_cloth=Waypoint(group_cloth,title='服装')sankey_def=SankeyDefinition(flows=[(w_elect,w_home),(w_elect,w_cloth),(w_home,w_cloth)],waypoints=[w_elect,w_home,w_cloth])data=pd.DataFrame({'source':['电子','电子','家居'],'target':['家居','服装','服装'],'value':[100,50,30]})weave=Weave(sankey_def,data,link_columns=['source','target','value'])weave.to_widget()sankey_def.flows=[(w_elect,w_home),(w_home,w_cloth)]weave_new=Weave(sankey_def,data,link_columns=['source','target','value'])weave_new.to_widget()

TODO:上述代码在2.0.1版本,跑不通。

优势在于它把“流”的语法抽象得非常干净,几行代码就能出专业级桑基图,且配色省心。

不足,高度绑定ipysankeywidget,只能用于Jupyter Notebook或Lab,没法直接导出PNG或用在Django网站上。