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

Python 如何画出漂亮的地图?

[复制链接]
8 F7 ]! O6 D: [% ^0 k" |
U: ]8 _! X7 l8 p' R

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

p2 S3 C/ v# ~& L
7 R9 e" I" V* z$ E( e

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

导入包,创建一副世界地图, r, A5 \5 N% J
import folium # {' i4 a$ a, f6 K* _* H import pandas as pd 1 n, B$ f* L0 o- n) Y2 A * G' Y. A+ C9 }% h # define the world map0 K9 U; c, G4 d! Q8 p9 Q% j, ~7 u ] world_map = folium.Map() ; K1 Q& @7 B. @, q 4 Q' V: B: O& t& [+ x5 q # display world map 1 X0 M! t; u0 W/ n world_map
. E6 Y' g! A1 \
1 Y2 I1 ^+ n, u1 c" V# S, ^' p

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

4 { U+ @/ b$ t" @ c2 T7 z ?
# San Francisco latitude and longitude values * J. o O j: W latitude = 37.77 6 @+ z7 X! n% N; F, F' U t longitude = -122.42/ Z. h' A3 I! s$ p \3 D5 G( G ) C) ?- B0 ^, |6 `$ _ # Create map and display it ' W l0 a0 A3 o) ]9 H3 Y san_map = folium.Map(location=[latitude, longitude], zoom_start=12)2 N7 F5 W6 ^- U4 U' \0 G2 P : j2 g! q3 f! ]6 [ # Display the map of San Francisco 3 \. ]/ [0 U/ K+ `( W san_map
, n3 d4 h/ j0 r6 d9 b
: K5 Q6 j1 ^9 k5 d8 p

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

# \7 c2 a3 N7 y+ D+ m( \
# Create map and display it7 t! x/ n. }( l U1 o- E san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) ?5 ^2 k3 f% z# W6 a( y
7 s' K$ j& w4 B3 a/ u6 m! t

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

; x! Z2 j; d7 y( @' Y
# Read Dataset 2 _/ A0 S3 `, T( p$ X T P- {1 k cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)" Z% P$ o; R* i9 G; ? cdata.head()
$ z/ k) M, z; g/ X* }9 f8 t/ _
! K4 W0 e. C9 K+ f' Z I

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

" s4 _6 b2 g2 w2 j( m1 G
# get the first 200 crimes in the cdata9 U$ ~( t2 Y, P# N, m limit = 200+ M' {* [. m7 B+ y7 [5 |) I data = cdata.iloc[0:limit, :] T' q& G5 g4 V) A: W6 S% p0 Y% F% A3 @$ _! V2 {2 ?" r # Instantiate a feature group for the incidents in the dataframe7 E- |5 d: g+ Q0 F& D% }5 M incidents = folium.map.FeatureGroup()7 K" c6 x d6 S/ a! Q5 S% ?; Q / |0 W/ [ v( Y9 J # Loop through the 200 crimes and add each to the incidents feature group ^6 Y& b# u# k ^- R for lat, lng, in zip(cdata.Y, data.X): ; a% U R4 y. |% j7 J1 |% b incidents.add_child(& J3 o2 }- x9 \+ a0 y" M folium.CircleMarker( 8 p: N+ v' c$ H2 k* x F [lat, lng],. i. s' p7 W2 s+ a' r- ^# s$ K radius=7, # define how big you want the circle markers to be $ z8 a* E* Z9 {) V. V' h- k color=yellow,9 V) m) j. X$ Z fill=True,, t7 J# k, }2 u* B# l fill_color=red,9 \3 c9 h5 ^( i$ J o% {4 q" d) p- H; g fill_opacity=0.4 1 r. M6 n' I, I4 x% Q, {6 O ) 8 g$ \% j* K/ |3 E ) 6 t- k, B8 E1 e+ R# n! a% Y- \2 }( s8 Y7 T$ x # Add incidents to map2 Y, e( M0 [# g! F. a Z$ n6 B san_map = folium.Map(location=[latitude, longitude], zoom_start=12) + C9 x3 I4 `/ e9 A san_map.add_child(incidents)
+ H- p' v$ R# I
$ `% L: v/ }; x J/ h( x8 ]6 f

5. 添加地理标签

, G, T, o; F4 @' E& h+ m# m0 @
# add pop-up text to each marker on the map' D. o* ?! ~. |" U: w% Y$ D latitudes = list(data.Y)0 V/ `; q, b! r4 G+ E. Q longitudes = list(data.X) U) T1 T- \- r# l$ H- w& e* {6 f labels = list(data.Category); T7 N) D( o* v% ?: l % p4 {- n- f- e8 t4 I3 q/ ^/ C for lat, lng, label in zip(latitudes, longitudes, labels):8 {1 q; s+ v( j! r folium.Marker([lat, lng], popup=label).add_to(san_map)& b a. g$ p" t4 ? # X4 f. w, T7 ^) E5 P$ P! c' G # add incidents to map . ]9 `0 z9 A' Q san_map.add_child(incidents)
5 l- G( g7 ^3 H& @( O& H% X. \" I
3 Z3 R+ L4 [/ _3 E4 p

6. 统计区域犯罪总数

& F% i8 P# L) G9 e3 b7 K! x
from folium import plugins4 b# C( \- m1 W% w X $ e+ r! A) |2 [ # lets start again with a clean copy of the map of San Francisco4 `$ j+ s/ e9 o% T# s4 ? san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)( |& r: c' S \, V. O! i % R8 U5 r' A0 s4 y7 o- E # instantiate a mark cluster object for the incidents in the dataframe 4 Y4 B& e) ? h. @; c* \4 H, l incidents = plugins.MarkerCluster().add_to(san_map); k U2 L. Q" [# |' I3 z- w2 a + {9 e+ T& a7 A8 L; u # loop through the dataframe and add each data point to the mark cluster 3 ^4 t7 z1 N* }/ y+ m/ T for lat, lng, label, in zip(data.Y, data.X, cdata.Category):2 l1 ?1 U& r! P2 T* j' G folium.Marker( * w- a8 f9 q, _8 G' r location=[lat, lng],3 l- _( H/ J/ a/ ]' k/ z icon=None, + H# g3 Y0 m) |1 g popup=label,: X6 w; A+ `$ P; r; \) ` ).add_to(incidents)/ A6 s1 b9 W" G) y3 h/ k " }. F* C, V. K" H( V1 E3 T # add incidents to map1 z. c% [$ M' r7 Z3 A san_map.add_child(incidents)
/ ]5 A% d# m) p7 e! U2 \
& Z: H% F9 @8 K5 S& o4 {' u

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

6 \% m" W! h) l" l( h% S: i0 B
import json* M x9 @' _# i3 ?; b f7 j; J import requests8 G; Z0 P! X3 I x+ y4 g! M" F 1 R* g6 G5 e) l- o% M6 C url = https://cocl.us/sanfran_geojson 8 L2 P7 G* ]9 ~ san_geo = f{url}" ] ?2 c2 g: _& x# n$ m san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)) s6 L4 W, A2 q+ n$ |. ` folium.GeoJson( / o8 \" Z& j$ p! \+ P9 ~. f san_geo,7 \9 q8 I5 H" F# n8 E! p/ Y% o style_function=lambda feature: { / v* Q- N, Q0 d) n8 @! x( j fillColor: #ffff00, 5 H! U4 i+ w% j' z, E color: black, & E$ D% p% z; _, o+ W9 U- X/ m weight: 2,0 L( t; O I9 O9 N! g+ m4 c dashArray: 5, 52 k+ ^0 }( o9 [2 i6 }& o5 j+ \ } + b( w0 N5 V4 a! J6 k. I! K7 J ).add_to(san_map)# Z. d4 m2 i: p# T : }5 }0 l' a* F3 c4 I% m0 _" b #display map0 _8 \3 [, t% C' j% O' S san_map
% K: ^( y+ `7 C
' |" D! j* _' ?/ W; t3 m. ]

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

1 l$ S" c& C: c- c( Y
# Count crime numbers in each neighborhood* h: n0 L( I! c# L2 X+ j disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) ' K' x/ V- K9 q& @ disdata.reset_index(inplace=True)6 ]$ b2 z3 J* ^+ V) t" R2 g0 T3 _ p7 B disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)' |; |$ f/ B- _! c disdata
) Q7 d% H Q9 U {
! F) V$ C4 _0 Y! Z

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

( n+ t/ n8 [% E) v f
m = folium.Map(location=[37.77, -122.4], zoom_start=12)4 T+ z; W! {4 q ^- Z6 X folium.Choropleth( 0 {" ^+ I8 D4 b* r geo_data=san_geo, 7 y3 o: M9 | ]" V" \+ L+ g data=disdata, ( u( c5 f7 T$ s columns=[Neighborhood,Count],% O$ l2 a5 Q8 I* L- a; Y% z key_on=feature.properties.DISTRICT,% z) \+ l! V, l #fill_color=red, & C) t! U4 X8 r0 g6 P fill_color=YlOrRd, - N$ p1 T' U8 o. M+ q fill_opacity=0.7, 2 s2 G u/ q9 k( Y; t. C! ^ line_opacity=0.2, 4 o3 X. m `2 r highlight=True, % ^2 c; W$ l* o0 w legend_name=Crime Counts in San Francisco 8 \ t: _3 p% `3 u ).add_to(m) ) Z- l. a6 |9 W" z7 k: g" | m7 w3 H0 y# b" M
( \: v( m: G7 F' M; j( i) X! p( q
: b) G5 c7 {3 X! \) N+ e' D

10. 创建热力图

1 m; v6 Y- ^# N3 z' ]" X/ d& W4 ?$ @
from folium.plugins import HeatMap 9 T' X# ?# A0 [! ^ / _5 z6 f2 h( e # lets start again with a clean copy of the map of San Francisco! |; B6 G* F- A7 m$ ^3 V1 T san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) ( D0 v# ^7 P3 J; J* q6 x+ n. E6 g; P+ X" C # Convert data format ( w- v. C5 U* u1 f- Q5 A heatdata = data[[Y,X]].values.tolist() 3 I1 _$ x2 Z- T. n# A/ R3 Y! P5 T+ i' i& u" t& e6 p # add incidents to map9 D8 @! ]7 ~8 i! ]; Q1 ?4 G HeatMap(heatdata).add_to(san_map)( k$ f0 J \9 T( ~# l: B+ j" ` 0 A/ ]( E" ~( ^2 | N: S0 v san_map
, x# [$ @$ y4 \# y% u6 N% \0 o
- w0 ]/ U- V. p. z8 U3 w

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

, M7 N! ~( N/ v% S* c# f

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

+ ], |; b1 t. T" ]. F
& P) X1 s" W$ {+ q4 M# C ^) s

我的其他回答:

9 O3 j5 D4 h" A P # d/ @* L5 ^! ^5 c7 ^% o( Z% k 1 V3 J: q+ p0 B: b # s# u7 q+ M# k" T

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

* Q- D" M" j: |- n7 t3 g

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

) G6 g' p7 u1 l/ R

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

6 }. Y" u r) }7 @& v' ^

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

/ C/ a' M, t. i& T6 J; Q; F

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

: M4 s6 o# {9 s3 [% K/ C) V
5 E" i9 S* x0 ]# r 4 T @- |8 V0 j- o. `# B ' {' w, h! L, ^6 S ! ~! U" u. T6 S H D/ a& I ( c( F8 K8 W9 L" a1 c7 K9 O
回复

举报 使用道具

相关帖子

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