Python 如何画出漂亮的地图?

[复制链接]
' _ w; d0 G' e) \0 S
1 M% V. b+ y u: I$ {) [$ l

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

0 N f( w, K0 [$ N' S
# w' G0 ]/ |0 J, X+ d1 q

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

导入包,创建一副世界地图 - \5 f0 L! |/ q
import folium ( ]/ A$ d* E7 ]5 w$ O: a import pandas as pd 6 @% a [* i4 F* ~ v. @" x4 ?1 s g. E# d3 E: u" j # define the world map ' i3 }, z/ I' P+ _ world_map = folium.Map() * y1 [' A6 Z2 I$ T' p8 D R- s- Z" H7 f # display world map$ V2 _* K- J V1 u: O world_map
: a5 w/ `: k1 w3 j
" Y8 @# o- c& f/ B% H

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

4 j% u, c) g @% q5 i, ]& g3 n
# San Francisco latitude and longitude values 2 @/ y* ^" |8 {( J, z% L latitude = 37.77 , Q! i* n+ }! I3 l longitude = -122.42 ) A& q* J& f1 G9 x4 S8 O: {* x- b+ ~ B+ @ # Create map and display it) [8 R& N: o6 l) ~% I% A san_map = folium.Map(location=[latitude, longitude], zoom_start=12) , B8 _8 z2 p, n/ k7 C/ i5 R8 x* ?: I # Display the map of San Francisco 0 i5 v5 V. s. O% h4 f san_map
9 e9 G8 @7 u$ G0 e8 X
7 c& ^/ o/ w6 r

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

: t2 }7 m" [; r
# Create map and display it . L7 Z+ v' M( U5 r( R; h san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) t, } u! X4 I3 `& K: n' s
" r# @5 F2 e* p7 _- p0 X

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

. Q3 a/ d4 v7 D0 S
# Read Dataset ; b9 [& [8 o; [6 N" b9 \/ Q; N8 k cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset) 9 }9 a4 V# D+ y( e+ a7 f4 @5 N cdata.head()
2 |1 b# c" q! a8 _+ e1 a: w5 W% x
) m( v( Q$ @7 T% Q2 j( {: e( ]& Z3 I

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

9 O( E7 c0 s* ]/ d* j" V
# get the first 200 crimes in the cdata & r$ w) W4 z2 E B k) _ limit = 200 5 f7 n7 Z+ u/ S+ a5 z data = cdata.iloc[0:limit, :]9 u2 U7 l: z# [& C; A$ W 7 R/ j% f. U1 i; P8 \+ | # Instantiate a feature group for the incidents in the dataframe " ?9 _, X6 `1 x2 v- W6 U incidents = folium.map.FeatureGroup() 3 ^% j# X# g8 g$ W6 c6 e1 K) d . k3 M+ |7 v: Y+ } Y9 N # Loop through the 200 crimes and add each to the incidents feature group) D) X3 G1 }# i$ p4 r k for lat, lng, in zip(cdata.Y, data.X):2 O. q; i _, h! ^3 M6 k* Q incidents.add_child(- U" J# m/ h, ~, ?9 ]9 M) x folium.CircleMarker(" _% w' q' M5 _ f9 s3 U- A [lat, lng], , [) N. b; b3 N: V5 i% K" p radius=7, # define how big you want the circle markers to be! U6 J, I3 ]/ D9 U# h( N color=yellow," w; z- t+ ]9 {, Y7 ^( o. H+ Z& ? fill=True, ' p7 e# J6 F& E; x z4 a fill_color=red, 2 d3 R q; X; g fill_opacity=0.41 q( v7 n3 Q# @9 z" l. l6 k ) % i, M9 y" k* R! o* q3 W' _+ q f )' J' q/ p. E. X) _3 p4 Y 2 h9 [& w# W8 M3 _% F3 k9 s; } # Add incidents to map6 p) i# m' t9 g4 _6 I, m san_map = folium.Map(location=[latitude, longitude], zoom_start=12) 5 H& Z: X, K# z* S san_map.add_child(incidents)
& M2 L$ R$ ?, K1 M* l. R$ N
7 V- L4 `6 R, h+ J# B

5. 添加地理标签

- _1 c: X" q5 w7 l0 D
# add pop-up text to each marker on the map + P2 Q; B6 q+ z3 v9 y- R+ x latitudes = list(data.Y) ; s( s- I9 I, H longitudes = list(data.X). }* [; L. K9 a& ~7 M labels = list(data.Category) * q6 l& t6 Q. {0 Z3 j9 ?; B: V) E' y- u* c for lat, lng, label in zip(latitudes, longitudes, labels):8 {* Z) R& u2 U1 S0 ^2 x9 I0 P8 O/ w folium.Marker([lat, lng], popup=label).add_to(san_map)$ e- v2 H# ?6 n$ ] # s6 ~( k8 Z9 \1 } # add incidents to map; |6 j2 v( `, N- H7 X! v6 W" d% J san_map.add_child(incidents)
6 z' v. A; E& @7 t: d
?3 z. f( w7 U7 J' R; I/ p

6. 统计区域犯罪总数

" O: t+ l: q3 g U, R2 ?
from folium import plugins 0 d+ |& Q+ W' Y, ?5 F4 K( ^2 r) T1 V2 ` # lets start again with a clean copy of the map of San Francisco' L2 w- v; g, b4 z& f, Q, w san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) ) s* P4 Q V& z" Z, E: [0 y- z% l* E& | # instantiate a mark cluster object for the incidents in the dataframe) }4 b7 A9 L h2 [7 ^+ G8 I incidents = plugins.MarkerCluster().add_to(san_map) 4 p9 P/ f8 g N / e) W0 N# T. h! W8 n # loop through the dataframe and add each data point to the mark cluster 6 {2 [' v) }# v for lat, lng, label, in zip(data.Y, data.X, cdata.Category):* N, T) v& a: K* B1 ~4 D$ h- K7 y folium.Marker( 3 U% K; h) W% e4 p3 K location=[lat, lng],+ ^! A. Z, N% g! D icon=None, 2 n8 F) R+ y: m! s; |+ R popup=label,6 C% W2 f. V6 u6 o. W ).add_to(incidents) # [9 t5 z6 s" j8 H# x / ?) \" ^3 f8 g @- E" H # add incidents to map& j4 H; P/ V$ H' I san_map.add_child(incidents)
" ]+ L" r- B* r2 G5 c
; }! A# o8 j1 q: y- e4 z$ Q

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

) S' A/ p. u8 ~3 n$ @6 [1 e
import json( _; |; }/ l- c- C9 R/ ` import requests1 C7 d; A Y( |6 n8 m7 K ( ? l8 y l @ J9 } url = https://cocl.us/sanfran_geojson) V+ g6 N. b" y8 w0 t0 V san_geo = f{url}. \( a4 O- _% o2 V' t0 t san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)0 Z9 w- u* G8 ~ folium.GeoJson() J! h1 W! c& g) A san_geo, : ]3 k! @' }: x: R7 x1 M style_function=lambda feature: { # f/ u9 I6 G+ m7 W+ { fillColor: #ffff00,' h5 ?: w0 K5 v( y; h( X+ V color: black, / c6 [( m: Q$ |, s+ A weight: 2, 9 f b% q/ w( o$ R dashArray: 5, 5 * @, P4 I* W0 l2 d; U } 4 w; V5 t- G* ]* t& p C6 t: ?6 R ).add_to(san_map)5 `8 g& D- }6 L% e . P" M# C2 ~* ]2 z" \ #display map& s% Q& ^" k0 }- v/ m6 ?3 D san_map
7 G, t6 p; M' s" q1 q
/ j3 X" U9 Z) h$ P( c( F

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

& k% W$ F" }! `8 j& L% S/ @
# Count crime numbers in each neighborhood 5 {9 e8 I; y; O) m$ S disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) * t; R; b0 N5 n' R: J6 v disdata.reset_index(inplace=True) # _3 A/ v% s( d disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)- v: S3 o+ x& a4 [ disdata
" F% V& h8 J1 M' F
* k& b& y/ B- `( h4 q- J- G" E8 S

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

% Y, W' j: b2 Z* |8 M6 P
m = folium.Map(location=[37.77, -122.4], zoom_start=12) % C) ]* q0 M% A8 \ folium.Choropleth( ( S7 U: D: B/ _ X) ` geo_data=san_geo, 1 R- [% W$ h1 s8 x data=disdata,2 _( k# t5 Z- m) [ columns=[Neighborhood,Count],/ m: B7 q+ Q8 g! v; n# Z key_on=feature.properties.DISTRICT,; k1 f' |; R e) ]9 k #fill_color=red,- C9 X- P& @, Z7 _ fill_color=YlOrRd, # ^6 Z& i8 t. u! o" K; p fill_opacity=0.7, 4 ^+ x1 X0 I8 C4 v: J8 f line_opacity=0.2, 8 _5 ^8 I, v( G1 r% E. Q. G highlight=True,7 x5 J' {! Q4 }* C5 g( X" T legend_name=Crime Counts in San Francisco: K3 N: t: w& J& c ).add_to(m) A* a0 |# g; [2 g) U m 3 g. l4 m6 u; ?: I3 `# O& Y4 I
, r, t0 U0 O. J! c
( q) L) `4 q6 D: }3 q8 S: o* Z

10. 创建热力图

3 X! P" `4 l' q
from folium.plugins import HeatMap: o9 @# }/ Z8 w) k ( ^( d8 u! ~, C0 G0 o( s7 j # lets start again with a clean copy of the map of San Francisco / F+ J5 Y! K0 o san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) $ R8 }, |6 ]! ^9 n0 X1 E$ R {7 \* s # Convert data format0 C6 ] Z) D" g9 V( f% K( b# Z heatdata = data[[Y,X]].values.tolist()& R: O5 U( _0 j' g " s3 T& [2 O' F* c # add incidents to map 8 t! U* C! o' ]& N: p6 k' _; a HeatMap(heatdata).add_to(san_map) + Q- g# B" G% E3 F7 x0 w2 b * Q! u* e4 w5 E san_map
& `9 B) I8 n2 E2 B
" j" S0 ?0 u% O- O

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

' L# V, @ t- A- Z/ J

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

% k' t4 M* h* ]3 u) K' E; A
: t, L- b- v+ W, g! H

我的其他回答:

- E. f/ ~: G" H6 r6 e 8 n2 E& h, `& N ' S0 |8 i% m' s0 q" v& t , {* q- s& x- T' b5 c! n2 |. l9 j

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

1 r/ I- `" X9 f" s! ]7 F ]0 F

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

! b+ @7 Q$ T$ [# y% y

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

3 o4 M" N7 b: x# p

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

' _6 d; s( Z% @+ u; m

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

P* \2 q) R5 K# S6 E
3 F/ `6 K: A1 G , z4 `5 G6 u) _! Z) k* ~ . p, G) [- r2 G N6 d- ^& ?" U6 ^: Y5 X) G' [: N/ x. t7 { / ?" I5 |& P' P* R7 B" X+ _. `
回复

举报 使用道具

相关帖子

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