Python 如何画出漂亮的地图?

[复制链接]
& ?' J" A/ [) {8 t# K
2 ~7 j. U/ d9 Y# g6 \ E* h

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

' w4 H0 I+ S* I
$ ~! |5 T- K/ M! T, L; ]4 y

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

导入包,创建一副世界地图" Y% U9 a+ E4 J/ u9 W0 c. f% @
import folium 4 h- c8 v, ^. k0 ^+ X import pandas as pd) `! \! H* R4 D$ X+ W 6 I; x* u }9 l: R, Q+ k # define the world map 0 @# ~* X8 y4 l9 V* v* {$ k3 X world_map = folium.Map() 4 p+ b* H# U5 z. c# Q& {6 }+ K& C& U$ X+ ?# [: T/ e4 Z7 I0 H) y # display world map1 d; M* e; X3 k0 c world_map
& T3 ]1 l: K& I6 H9 D+ i
4 [* t; s" m! n3 v

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

: P0 ^" C+ }- ]: Q0 O/ P# V6 |
# San Francisco latitude and longitude values ( F! r# c8 t( E+ Y latitude = 37.77 7 q3 n# e1 b$ P9 ]) u9 h, Y+ W7 M* X longitude = -122.42 % [: ^4 O* ?% s# R7 h ( F+ U0 v2 f# Q, g5 ? # Create map and display it 3 H9 Z+ `6 B: v' L* e( S4 z san_map = folium.Map(location=[latitude, longitude], zoom_start=12) 9 l0 M0 y( k( L: @ # E4 `$ K4 U0 \' w9 ^ # Display the map of San Francisco# u V; W- q' x, | |' c; Q8 R! h san_map
9 {# R' U" f( U2 {: e! Z
# r( F- Z/ t& s8 R, s

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

8 G% e5 ~, q4 \3 K
# Create map and display it $ p7 a2 h& J' A1 v* {$ _7 y san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) D2 k4 ]. I3 u ~, N7 p2 s
! P L6 p2 t0 ?, k7 s9 A( J

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

) i" t, g: X! r; d
# Read Dataset+ d9 V) d9 ?) }' Z1 X9 V1 Y: { cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset) * O% r3 |& N* e0 I$ q cdata.head()
- S' ^* F& W# s: y/ X: W& E
2 H7 _% B% _& F

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

! n( W0 J$ a7 s7 u9 z- D( u
# get the first 200 crimes in the cdata . m% D% d- T8 l; @/ c" m# v limit = 200% m! T8 }+ V) y& H+ Y8 m6 @8 d/ Z data = cdata.iloc[0:limit, :]2 T( K0 X3 V A( [* i $ |. N5 K! g* j4 F. ?' x T# C; { # Instantiate a feature group for the incidents in the dataframe6 l, O& A* B4 l+ A/ G incidents = folium.map.FeatureGroup()5 S# Z- G' e1 X! Z3 J ; Q6 v3 \/ C! M1 M # Loop through the 200 crimes and add each to the incidents feature group % L8 W) r: L3 Z for lat, lng, in zip(cdata.Y, data.X):/ [! c8 _' |% n' r& z, E# d* S incidents.add_child( F. C e8 O9 r' K; S ? folium.CircleMarker( & ]; P' x8 z9 j3 e [lat, lng],5 [1 z) ]) k$ M) @7 w( y radius=7, # define how big you want the circle markers to be" t) D; ^# h3 i# L0 ?6 Y( H/ ^ color=yellow, & O) o; N3 y' |9 r) e( X fill=True,- O8 g. h! L f# N fill_color=red,8 G& l0 F* Z- t+ E' `0 v fill_opacity=0.4 , J6 A2 H* v; R2 M) T$ |7 c( j ) * y- b7 m a) ?$ x) O ) ' f9 }& W5 Y7 K- f" ] - I: _& p0 T* h Y$ }, U # Add incidents to map $ M" ]2 ^1 ~4 j san_map = folium.Map(location=[latitude, longitude], zoom_start=12) 6 _3 L/ U V+ A' c: u' P san_map.add_child(incidents)
% w- _2 U; F5 j. Z
3 V& F, d+ X& J, s# y

5. 添加地理标签

3 w6 U8 }/ P6 _5 [. R
# add pop-up text to each marker on the map # Q/ s: P9 d2 t; v1 L |* T latitudes = list(data.Y); r( T2 Q) x+ y/ h4 W* ^ longitudes = list(data.X) 3 l( R& q+ R- w; |1 N( W labels = list(data.Category) 4 h8 q# j, Y% H( l' Z- A/ F" b/ H3 ] for lat, lng, label in zip(latitudes, longitudes, labels):- b4 Q, z. r& m& _& ^ folium.Marker([lat, lng], popup=label).add_to(san_map)" e: G$ l1 |2 N7 F " g2 U; W1 U* E; D e/ X! d # add incidents to map # n2 H& o' A1 |, f san_map.add_child(incidents)
% u& L5 b; [6 v9 Q$ n6 D
9 ^! c+ D# A: o

6. 统计区域犯罪总数

' C5 ?2 Y4 g8 t5 ~$ E
from folium import plugins( J. B* e# f8 ^& R8 B 2 S" l& ?# N: M2 X% k # lets start again with a clean copy of the map of San Francisco 9 M' U* F' F$ T4 a) L- c! h3 c- |1 e2 { san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) ' ^6 e e x! a2 z9 e/ ? {- s8 l8 j, k # instantiate a mark cluster object for the incidents in the dataframe # u* E. n: R' a, \, d. k& s8 ] incidents = plugins.MarkerCluster().add_to(san_map)! R3 q# v% V& D% T" A1 S & W8 R4 g/ ~7 i" d9 s' j # loop through the dataframe and add each data point to the mark cluster D& h3 k6 L4 e" e5 r( R2 G for lat, lng, label, in zip(data.Y, data.X, cdata.Category): , F9 ^4 c+ I" a/ z8 g- o folium.Marker( 2 B. x9 \' Y' m1 C: |# E location=[lat, lng],# o* K& C. i( `# Y/ C4 V icon=None,; O, m$ V( U$ i popup=label,# I; X0 |; G' Y& G. Z" r# A( B ).add_to(incidents): X W1 l& F0 M: g; Y # F/ f" N/ }% h9 X # add incidents to map ( G* H2 g1 B0 k; C0 L san_map.add_child(incidents)
6 B! X0 J" s* k8 _
7 d- l2 E* s% t) e. z

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

" R/ s. p' F1 w
import json 9 v4 Q6 \9 p- u) j A6 `6 A import requests }* E! @; K/ O7 Q. j $ j) F- V ?/ M. g url = https://cocl.us/sanfran_geojson5 S* p( ?+ R3 s" @) v/ U% c0 X san_geo = f{url} 7 {4 L8 Q ?* }! ?4 V" Z6 ? san_map = folium.Map(location=[37.77, -122.4], zoom_start=12) ; q0 _, A1 G' j4 z3 x/ h" [0 Y folium.GeoJson(& }5 \- P5 j- R$ | san_geo,0 i' O2 `0 r1 M+ [ style_function=lambda feature: { m+ @. c0 M9 ^, G' b7 s fillColor: #ffff00, : H2 E% A, m+ g color: black, - m d9 z. E7 S) r3 Y weight: 2,/ j. J( q, c- o/ o+ W5 ~. _: a0 B dashArray: 5, 5 / T4 C- Z8 h' i6 H* f* }( ` } 2 C+ M; L% ^4 e5 H% R ).add_to(san_map) , B8 C3 O9 u- S; v* ^* @) ]) o' ^7 G( i5 V6 p X; E% Q4 ^6 d #display map! ^7 N: s: |7 A; h5 z' M( h san_map
+ Q6 ?' ]: l/ c' p! Q4 b+ e
% f1 O/ M9 l3 ?8 ~2 V0 r

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

9 ]# |7 k, d/ U6 O% c4 \: U# U
# Count crime numbers in each neighborhood @* C' i ^# k disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) , w/ U* }6 H( ^ disdata.reset_index(inplace=True)1 O, t+ I0 H( v8 G6 l. x" @, d2 V disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)1 O3 {1 U2 K! u7 ^! b7 C disdata
, m" }" i1 J+ A+ H9 J* b
! p2 @1 A: o1 G% F% S! ?

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

2 N1 y0 W; F) M& V( P. `2 \) Q
m = folium.Map(location=[37.77, -122.4], zoom_start=12) T4 W Y' \4 Y# r/ e$ M9 ]" L folium.Choropleth( K! u8 H, r4 @" ~: s geo_data=san_geo,, F9 l+ k/ q' G5 h7 m data=disdata,; J* z$ s" M9 Q6 S! C8 X/ y columns=[Neighborhood,Count], : s9 _& u9 H9 D0 L key_on=feature.properties.DISTRICT,, g r+ t4 c+ q; v #fill_color=red, : g9 y/ ~' U. I6 I# B- P fill_color=YlOrRd, ( d' q$ g; T9 K L fill_opacity=0.7, ! \- ~1 Q/ ~5 u4 H: ? line_opacity=0.2, . W1 t9 X! H g- l highlight=True, % d0 d/ o& A* B3 F, N legend_name=Crime Counts in San Francisco 0 S' ^. B; X- a. C7 b9 Z ).add_to(m) J- R0 j5 Z* w ^$ |8 N m3 ?* ~- J7 h. g
$ [6 I6 a, A5 Q6 ^7 ]' U* R
g. O* Z. M( T5 d2 O

10. 创建热力图

6 t) \) G: H# Q/ B& j
from folium.plugins import HeatMap! w, v$ g3 T4 h0 t7 N( a2 B * Q& L# b( U: h+ L8 e* r # lets start again with a clean copy of the map of San Francisco" v9 S- R% L; O+ j) _( S+ J# U% { san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) 5 P- n0 Y" G1 y2 A" P# L+ L. {0 v" j( c% d% O # Convert data format U' m' q2 n7 k/ Y heatdata = data[[Y,X]].values.tolist()1 K6 D/ ` K, j1 O+ W9 U ) {* w n; Z% q; _ # add incidents to map3 d: S: z3 B5 T/ b! Q. Y) j/ ] HeatMap(heatdata).add_to(san_map)- \9 `7 O, A% H2 b4 c$ t) m+ w 9 ?* F5 b% U6 [' B3 x5 ` san_map
% ]6 K; r1 e' D8 t1 M
1 h* J- M2 Z: Q

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

5 q( W% \( T6 q& A

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

& D% f+ L2 p. Y( \. J2 g
8 O# h3 b$ O, \. O9 A

我的其他回答:

, Z/ G# K# q4 T! @ 6 h# i2 l! i. R! z9 Z v9 n 0 @0 M0 i) N2 m" r$ ^, m ( u. W( H4 T- O2 s8 w5 T

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

: u9 \. d5 P# G+ U8 L3 V4 D

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

4 u& j( X6 `+ N: m! x" a1 f8 t N

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

+ p' W9 P; N6 g/ s5 I/ l

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

$ I( R% Y# A6 l1 @% j: J

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

( m; b8 H0 }7 X [+ T
N$ I, ~) G3 }- @" ` " F' u6 y$ M5 \% T2 y! u6 r : `2 `+ y: Y ^. R8 y( m. w* C0 E$ u9 Y 0 L2 y9 R: r2 F" }3 I4 M" x) R+ G

相关帖子

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