Python 如何画出漂亮的地图?

[复制链接]
; @( x' j9 _, @
& z+ o: C# _% y4 ^) J! B

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

+ ^& L7 H2 S4 s- p9 S
4 c$ k4 D* j+ G- `, k+ {

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

导入包,创建一副世界地图 7 p: o) R7 H6 m6 s/ r& r
import folium% `3 h4 x" N6 Q2 r% ?5 K* ~3 c import pandas as pd . j1 [/ r E1 g, [+ y) R/ X9 z1 }# O1 ]: F! k # define the world map 3 I. L |) Z2 i: I7 v world_map = folium.Map(): D& r6 Z' K1 J7 x$ W3 M6 l( u : f& @% [6 U5 H* F* _ v" g5 A # display world map - B1 Y7 g! I1 c- E/ d5 V1 K world_map
# B1 j5 p3 r2 m4 H1 `* O- Z" z7 N ^4 m" u. @
. T; r/ s1 D& ~1 D+ ?2 z1 [% I

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

7 w3 G6 \3 M+ \: y* h
# San Francisco latitude and longitude values5 \7 Q g3 h2 L0 j% h- E) l latitude = 37.77 # P5 C$ B% `2 ^6 C8 {2 u longitude = -122.42. b! w) e7 @8 x3 N% X3 \) n6 } + Y* n+ }5 M* t i( o2 R+ k' G W # Create map and display it / A3 }( x/ g- X san_map = folium.Map(location=[latitude, longitude], zoom_start=12)1 m4 @ j8 ?* M5 i; Z; ` / W% q; F8 s7 Q1 P' P # Display the map of San Francisco. G( m5 ~6 [4 f7 ^+ L! e# W3 V san_map
: [! b' D6 f6 k% [1 V. k
/ R- _9 d* c' K

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

3 D2 e; ?( `0 c% D
# Create map and display it 7 j) F" f! I! C* K& H/ u san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
( e5 c9 f2 l& Z" Z3 \( U
; R# o; [4 V f7 v

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

) t- _ j8 m' ~1 W
# Read Dataset0 x/ A- I. A# b cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)2 A) {3 ?, T/ Q, B- q* O" N! g6 o4 M cdata.head()
; Z. o# t1 [% v3 R/ E
$ s/ ]" |& r! N& Q$ R

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

3 {% q# I- I! _7 s
# get the first 200 crimes in the cdata 4 N0 V* G! O/ s7 y' ~ limit = 200 3 W1 f1 }. W* w% ~8 J: b. f4 w, T data = cdata.iloc[0:limit, :]% j/ C( F8 P% [. W" o) V ) u+ \* h' v1 X- a # Instantiate a feature group for the incidents in the dataframe$ W4 m( k4 \8 m1 K2 ~; r L6 y incidents = folium.map.FeatureGroup()8 X7 [! X1 U6 M: F" A& K ( q; x" O0 t1 { i9 \2 \ # Loop through the 200 crimes and add each to the incidents feature group8 a$ o0 d' [% X7 U/ o for lat, lng, in zip(cdata.Y, data.X):. ]7 v4 b z( G+ Y& x" v5 \ incidents.add_child( " x2 g; n* K) Y: Q* D6 c8 O4 C folium.CircleMarker( " I c4 s9 [5 M [lat, lng],8 {& ^( d2 {5 V8 N/ A1 _ radius=7, # define how big you want the circle markers to be8 l; k0 C$ n/ n8 h color=yellow,% ]- w3 e$ m! M8 c fill=True, " \# X! M, g0 p7 |$ C% [ fill_color=red, ) x, v/ ^, F- v' O8 r fill_opacity=0.4 3 X0 ^5 D3 e0 |* u0 g4 w# \9 v* ^ )9 u4 x% ^* l( B9 b- @8 g. r ) $ A" w) q3 q* D% @2 X1 z G) O! v6 i* Q- l # Add incidents to map5 j" }: \8 r0 ?, n% W/ P0 K; @ san_map = folium.Map(location=[latitude, longitude], zoom_start=12) 0 d6 G* Z( D; w san_map.add_child(incidents)
0 A: j' s+ M4 J( A
( o6 P! }6 ^" \% E4 |) s* ?

5. 添加地理标签

9 A4 M6 |# h% W0 q5 y
# add pop-up text to each marker on the map2 a$ X( |3 x. _: B, W: a' r( |) E latitudes = list(data.Y)& Z, ^8 [% c5 M! o longitudes = list(data.X) $ f% \1 e( o5 ?: S labels = list(data.Category) & N6 ~0 g2 S* k7 P1 L- O* d/ v/ b2 T2 _6 R for lat, lng, label in zip(latitudes, longitudes, labels): / }, c+ Q7 ]5 ^% g1 b L( ~9 A3 V folium.Marker([lat, lng], popup=label).add_to(san_map)& R' _% a% p- J, Z8 ~+ ^; @ * U7 ]+ h; E. P! s* y f # add incidents to map; j1 G b T3 X) ]$ Y san_map.add_child(incidents)
& f. Z; ` q( ~7 e
& X( M% O4 D7 V! G1 U3 T

6. 统计区域犯罪总数

7 [ J; Z) Y5 H9 {% a0 P0 i' Q
from folium import plugins ( t- R; f5 F' N: X7 h1 |; |+ U/ d( y4 ]8 d9 N+ q$ _ # lets start again with a clean copy of the map of San Francisco9 d4 ~/ b) |; c( F: a: ? san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)+ L) H% Q4 O& @8 N; n+ m- |3 N 9 M+ x- I7 h8 i! A7 F8 d # instantiate a mark cluster object for the incidents in the dataframe" G4 J( Z9 _$ S incidents = plugins.MarkerCluster().add_to(san_map) ( r3 }4 L5 |# l+ k- i 0 P1 Q) L/ f$ ]; w& { # loop through the dataframe and add each data point to the mark cluster/ i! `3 u$ J' G: [ for lat, lng, label, in zip(data.Y, data.X, cdata.Category):8 a2 {7 e1 f5 o6 x3 K2 g folium.Marker( / D6 {$ g& h9 U K2 |' D% X; @ location=[lat, lng], 9 D' K% Y- X( C, Q& `, ] icon=None,+ @) k2 \6 m+ v7 a7 R popup=label,2 T9 M$ [7 u- l; Y ).add_to(incidents)0 g8 p0 k8 A6 F K) A 6 Q* z, F4 F! I! X- Y # add incidents to map% F6 B$ g; ^! A v3 L& i5 F san_map.add_child(incidents)
9 k$ ^$ {' ~% q! `4 }* q/ C4 H
7 Q! O! s9 [# J2 ?5 B

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

* d3 ~; v4 l( O& h% v( {
import json6 \0 h, j( c* d; v+ _ import requests$ o7 G" B9 L+ f1 g* O( e; C! R 5 f* u, R% f1 f) @3 `: _! m$ v, K url = https://cocl.us/sanfran_geojson* P; r7 F# ^* c, p ]5 [4 @6 V+ K san_geo = f{url}' N2 C/ B1 u- g( V$ t2 J1 c0 g0 [ san_map = folium.Map(location=[37.77, -122.4], zoom_start=12) ) W2 D* k8 _& _! b, F" [ folium.GeoJson(- O1 _3 h9 |5 f/ F! z san_geo," i( M1 S0 E b" {- ? style_function=lambda feature: {4 v' o4 p+ @: F8 `7 `0 g fillColor: #ffff00, 7 d1 F* {, t5 a) Q+ O- \ color: black,( q, [5 w, T! [' l: G weight: 2, $ ]; w: B, W. w6 k- {- L, q+ R dashArray: 5, 5 ' i' S. m: Y' I6 s1 S K } 2 `4 O$ p- W9 m ).add_to(san_map)- n# k2 r. |% K# v9 U3 B + t4 Y" _" y8 K) v8 B5 F #display map ( } M7 H3 K' u2 `7 B san_map
# r# `& ? k/ E, V
! s' I% H A7 }( R

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

( \6 s. T) H/ L% o
# Count crime numbers in each neighborhood' s' U5 o8 @9 ^9 C disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) m- |6 R+ P! i7 {" G disdata.reset_index(inplace=True)) k7 {+ J1 [2 G9 @! C9 o) w0 R$ R disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True) 2 T4 C1 l `6 W) n$ N" h/ D( p disdata
/ Z1 I* C$ {. p' p: T
8 ~0 k# X5 A) {: V

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

5 E3 N' ~: N0 g1 g3 F ~* S
m = folium.Map(location=[37.77, -122.4], zoom_start=12) 5 Y/ ^; @) S1 o folium.Choropleth( ( t$ U# i4 r' C% H3 b: I* g- u geo_data=san_geo, 2 o$ ^) [3 N; a, S data=disdata, ! o A G! T9 u9 O5 H, @7 V% H( I# m columns=[Neighborhood,Count],$ L2 k# H; r" u1 P: Z t! J key_on=feature.properties.DISTRICT, $ c3 Z6 t+ ]& h: @! G. |2 R0 I; ^ #fill_color=red,8 ~) R! O, R* w9 c* ]" i fill_color=YlOrRd,# ^7 B' r- y( | j+ b6 E& R& j6 ?, c+ M fill_opacity=0.7, 6 ]% V, c! j6 d' S, q0 C line_opacity=0.2," ?( N5 p8 c6 w) D8 {1 b highlight=True, $ @9 O0 V3 ?1 G* X( y* \. k0 ] legend_name=Crime Counts in San Francisco: \, [! N5 i1 Z5 |! x- q ).add_to(m)1 S& d6 }- L4 V( o3 L& u4 ?! K+ L m& R+ T+ y, A$ \5 c0 Y
# O. Y, m+ I/ v$ h& O G& N% T! x
# e. m6 h9 N4 C

10. 创建热力图

: n7 N1 \5 A, H3 t; V* p- d
from folium.plugins import HeatMap) A1 W$ n+ |, v& R: k . @* j& I: A% Q" g7 W, P # lets start again with a clean copy of the map of San Francisco : J1 E$ A7 U2 h3 A; \7 j- [ san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)7 O9 @2 w; q* d# K2 q8 k2 G4 s7 ` 2 _$ k! a4 j9 q/ W # Convert data format 5 X4 @/ _; }# ]) ~+ U8 | heatdata = data[[Y,X]].values.tolist()- h) ?& q8 W3 r$ s; a2 ]4 R - D, B6 r0 k/ @: G6 B& i2 s # add incidents to map 5 r! [& u; }. z$ P$ u2 \ HeatMap(heatdata).add_to(san_map) 6 o. V9 @: z% W; u* |' F* n7 S6 Z% w( B$ [: `6 j& p! W san_map
+ Y Q) k! }9 N
! f e; r" b6 n# {# h. w: g9 E

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

1 |" E6 o. c! n7 W+ n. ]( K" ^

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

8 o: b. x& F p% Z0 k
8 S: V3 Z- j: ]0 N

我的其他回答:

" q2 S9 Y% f; n9 d _ , ]2 {5 A7 h! e. J5 e 2 X3 m$ y% j$ O4 o$ y% k1 ~& G" N m & G; @% ]7 T; _9 H0 Q+ A

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

Q1 N" F+ E/ C9 G

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

" y7 P) c$ t0 f, c+ u

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

2 M' n3 v9 S. X8 u% G

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

- ]/ f/ g8 e- \" T

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

" ]. H2 m# y: l" _' m' y7 M
* W! {& A; S) E' a - Z; N B* n* P- z; l% N ) V! c8 E) d# ^6 p* V/ k( P* S4 Q3 n% L3 s' ~: Z- v0 N' p9 } ! j" ?/ j- N" @( Y& J( e: ]# r
回复

举报 使用道具

相关帖子

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