收藏本站 劰载中...网站公告 | 吾爱海洋论坛交流QQ群:835383472

Python 如何画出漂亮的地图?

[复制链接]
% A' f* ?, g. \) B1 `4 _
+ W& @" q [7 g; p' V2 _

推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里

; v0 ~ o/ S& d
, F& j3 O4 k8 ^! Q! t

使用方法很简单,操作如下:

导入包,创建一副世界地图 , }: P' I5 g* V, O
import folium" t) E* L, @4 f( D8 m8 o# w import pandas as pd ' k. X# {+ {( P) w9 M' ]! v* H1 E$ F$ E% X7 ?! H # define the world map ' K9 Y0 g9 g5 v! ]) ] world_map = folium.Map(); |3 |8 L# X, p/ V0 O, E' W * y. k5 ^6 F. ]4 }: A w # display world map2 p r' b. V2 v1 S% C' ?8 c( Z g) \2 n world_map
$ r; h2 l+ } S- Q# M$ ~
* b1 n0 c* R! U% t# Z; g7 F

2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。

& v# m( ]+ K- b" X
# San Francisco latitude and longitude values : t8 k; O) P/ l, _ latitude = 37.77 ) @; H9 h$ b' H7 C# O8 d6 z# j6 D4 Z longitude = -122.42 - q6 }% ^* I/ f5 r * h- J7 k* ]; _ # Create map and display it ; _4 X1 o/ `/ N- c% p( V: f san_map = folium.Map(location=[latitude, longitude], zoom_start=12) 8 g. C. c8 p N2 X * q3 c8 O1 @/ j) j0 {! K& r' ^ # Display the map of San Francisco , a# d; }! q3 N3 ?' _# h san_map
2 Y& q' G H% Y# {, b$ k8 E
7 s& r5 v8 G' ?6 K$ `+ M5 {% t) c

更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。

0 ^8 h9 C; J: s, K7 x
# Create map and display it7 H3 w1 U" \! n# Z& h3 N8 y; { san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
! \# _! F& z. j! @5 L6 F
) g1 F+ \* b8 h: E& K+ l; Y

3. 读取数据集(旧金山犯罪数据集)

; S$ g3 x6 F8 `( B: n. ]0 p
# Read Dataset * q2 {( e r, f% ]2 C9 l+ x cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)- q) P. e. p% p cdata.head()
" l& y- i# C) q
5 I8 s9 w2 T# f+ Y$ b4 S

4. 在地图上显示前200条犯罪数据

# E: Y2 i8 A. ~- E9 Y
# get the first 200 crimes in the cdata3 \3 p; B% d, }# v limit = 200 . E+ L9 h: Y% b z4 { J data = cdata.iloc[0:limit, :] / |, a& Z0 \. v7 c 0 f5 J5 @# G$ _. E # Instantiate a feature group for the incidents in the dataframe6 {# A$ b$ A6 O+ u incidents = folium.map.FeatureGroup() 5 {5 ]$ N! h! r6 x* K& ] 6 M# A" @, ~% K4 M # Loop through the 200 crimes and add each to the incidents feature group * O/ `6 z) z; ]( m. h for lat, lng, in zip(cdata.Y, data.X): & K) S7 v9 i. T! T! e/ ~4 n incidents.add_child( 6 u- j8 L: l/ J1 q2 g5 ^ folium.CircleMarker( ' m2 H: {2 j8 H [lat, lng], : I. F) G9 |5 Q9 n- \5 q/ C radius=7, # define how big you want the circle markers to be' u! x# e4 n. \. k3 V# l color=yellow,4 U% I6 v' ^/ ]% F, B fill=True, " X! [# n1 P' k% e fill_color=red, 6 o/ b0 R/ n" i) o V8 t' U fill_opacity=0.4 # P- t5 V: y% m5 Q2 K# ^8 n ) 8 \' T3 U: E3 R9 `% c )$ Q8 [% F9 f$ x B: S6 Y4 G5 \ 5 J4 A3 G. k. {2 S- s- U! h& T# G # Add incidents to map3 U6 |! K! e& ?8 q' B& i san_map = folium.Map(location=[latitude, longitude], zoom_start=12)3 {/ j: U* u8 R N# R$ }- H% r# H M# l san_map.add_child(incidents)
8 d2 K6 R' v; W
. i! k/ b; z# p6 @

5. 添加地理标签

2 ?% k6 f6 Y% a) ~4 H
# add pop-up text to each marker on the map& U' U2 f! C, N* w9 A ? latitudes = list(data.Y) ) ^5 N6 c% C" S% I longitudes = list(data.X) ( Q$ ^1 |; l" J8 R, R* D labels = list(data.Category) 4 v; B& e( A! u4 t8 T: j6 h7 H% D7 L8 ]( t5 X' @+ o- Q0 g for lat, lng, label in zip(latitudes, longitudes, labels): & E" C& `+ m w s6 v/ S folium.Marker([lat, lng], popup=label).add_to(san_map)) e B+ @. h- k4 T* x6 j4 y2 x 9 J( P( }/ m$ U6 X$ j j+ j # add incidents to map & @0 E4 m) w$ ~$ @" P% L! ]& y, | san_map.add_child(incidents)
# [. D, N) C: C
" q+ E: f: L0 ?/ b7 D6 O* P

6. 统计区域犯罪总数

2 [4 U3 o' c3 ]8 \8 a6 X7 b! F
from folium import plugins 9 b4 ?1 R, D+ q X& U / R( G1 k6 |# { d9 b9 @ # lets start again with a clean copy of the map of San Francisco1 J3 n! y# j/ J$ c# k san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)# e+ Z J8 K6 q5 p/ @ # g$ d; o& Z6 M* h$ t # instantiate a mark cluster object for the incidents in the dataframe 0 |1 \" x/ X2 F1 k: m incidents = plugins.MarkerCluster().add_to(san_map)# `* X# l3 K* r& o & d" U% k7 I0 i9 } # loop through the dataframe and add each data point to the mark cluster + J& d4 [! L. T; S6 i Y for lat, lng, label, in zip(data.Y, data.X, cdata.Category): 9 u( S1 M4 M5 O) Y folium.Marker(; Q' ~- e! L e location=[lat, lng], 1 h$ t' h" R; y7 y0 u- ~, Y: I icon=None,1 \: v; K+ I4 M/ Q8 D8 b* J7 c4 v popup=label, S$ b# s) e" c( c( D* | ).add_to(incidents)! n6 ~! o4 M6 \5 y 7 e1 y9 u+ L9 o4 P8 b; t # add incidents to map 8 ]$ S& C" X0 x { san_map.add_child(incidents)
& z1 @, @0 L' j$ Q+ z N
8 P6 K6 G# \/ e2 ~7 I4 _: T

7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界

0 l" i3 C& T" P) }2 w3 E
import json/ M7 B+ K+ h5 S' H* _) y0 ~- G import requests. q. J( R! N p % X7 _+ y6 b8 k0 D5 y' M+ _1 I url = https://cocl.us/sanfran_geojson' P( U3 _ X( v t- V3 K san_geo = f{url} # Z" H$ q7 B, f! m: |1 m. O" X7 D san_map = folium.Map(location=[37.77, -122.4], zoom_start=12) 6 F( Z+ V+ F( R, q$ I" v folium.GeoJson(* U+ n) D$ _1 A5 U2 l9 p& I) n san_geo, - d: c; Q5 p" y; K style_function=lambda feature: {/ S$ i6 q1 F( C9 l7 l/ F5 ^ fillColor: #ffff00, ) d( v* o4 |0 D/ ]' { color: black,2 T% ~# u! I/ G. a weight: 2, 3 c8 J9 D* Z( s4 @ dashArray: 5, 5 * \ k% C9 L9 C" J }; \. ?1 R" k8 b/ n# p ).add_to(san_map) 2 n( H7 E: l( I4 j7 e. K: b6 z 6 a) Y6 C8 F; e3 }: w& n! X) C #display map+ {& _: a+ D1 c# o: U* x san_map
+ P- z# a4 z3 N9 P( U0 E- f
7 V+ h) S* D# S& n F) {+ R

8. 统计每个区域的犯罪事件数目

. {' K% D6 _" q' f; l% k4 ]6 D
# Count crime numbers in each neighborhood . A. D0 e$ I, k/ V, U disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) 9 ?0 n5 V* A- R1 Z2 l% I. `" _5 X disdata.reset_index(inplace=True) & `, h1 ~2 l3 W" x" ?/ N disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True) 0 W- I" H0 R7 N$ k9 b- k% @" d) D$ z: d- n disdata
$ f8 \+ E; d1 s- j4 r( l" P
6 J6 i6 M7 p( B+ q/ R

9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)

/ ?, a0 z# E3 @7 ]/ a
m = folium.Map(location=[37.77, -122.4], zoom_start=12)5 S. v" g& o3 ]: C l folium.Choropleth(6 ?1 p# J, R; g2 I6 ]# F geo_data=san_geo, 9 }% u1 t( `6 V9 I, H0 d1 E9 \ data=disdata, ( u: d8 z- E J* i; Z" } columns=[Neighborhood,Count],& o0 w( S7 r/ U8 z- e; Y6 i9 l) j$ M key_on=feature.properties.DISTRICT,- T! \" Q4 f7 Y #fill_color=red, ) b3 z% S. h/ |' W7 ^$ C7 j fill_color=YlOrRd,- ]4 O9 m, l/ g8 J" h fill_opacity=0.7, / ]# R0 b1 L% T line_opacity=0.2,5 L1 O* g, A& \ highlight=True, ) c' Q$ ?8 Q# @, M7 s legend_name=Crime Counts in San Francisco4 Z X. ~' m! K* R5 y) P ).add_to(m) - ^8 t i" m6 ]- Z m - F& s: U1 |6 G7 W8 G7 V" B
/ b& Y4 ^0 k5 P& e! k
, K& A0 R& I) D

10. 创建热力图

9 L1 ^3 W6 f, E+ ^
from folium.plugins import HeatMap ( G! S% `# T x8 x! d, p6 _& t! X- s% [' g- M- \ # lets start again with a clean copy of the map of San Francisco 6 G2 j# T- i0 |5 h" `4 ^5 G san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) ( D/ h, e" `, m$ t: k* T9 e 9 ?4 M+ T, S& N; b. x # Convert data format/ Y6 B0 Z7 e/ @0 ^ z- E heatdata = data[[Y,X]].values.tolist() 8 @4 a8 C; `* | 9 ^/ E9 A+ U) B8 D4 f, y # add incidents to map. k) t4 ~. @2 _$ u" z" ]9 b( | HeatMap(heatdata).add_to(san_map) % N- o& _' H; N* a6 @3 c! k- S& P - A$ A" L1 W$ y. Z- P9 _$ c san_map
0 f# k2 b: g& Y0 Q
. n Z7 Q9 o4 q3 b, X

最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。

0 W) G4 t0 Q, N- U& H8 z) e, |

实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。

) D; X! i# \* t0 S
E0 f% P, |8 T+ i# {/ u

我的其他回答:

/ N. V+ v4 s3 ` @5 w3 J* d$ E 7 I- j m9 V( E2 u2 [* R5 ] 1 L% T" H1 k N& r, ~

最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:

" m1 Q l) \! T6 [, o# d W- I

1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=

- x0 `( i3 E+ `6 I* }

2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。

' }- o; X& G6 Z% w1 m+ f

给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。

$ C3 O3 ?& k' ~2 S) k

最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!

' B* ~+ \+ y* X& z/ f' k7 J3 W/ |% n% r# p
2 K/ w2 |' d$ N: _5 C4 T* c2 P& o# g8 {2 Q; l( ? 7 h4 n5 w0 q: K9 p! m) f; W0 ^ & u+ o2 k/ z# R' b9 G! B* }# O; i% P6 B
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
风亥
活跃在2026-4-15
快速回复 返回顶部 返回列表