$ n' _4 a \7 c: i: l
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
3 f7 e# Q: ]: }; ~, Q9 [ : K' p X+ f0 d+ K. K* M- d
使用方法很简单,操作如下:
导入包,创建一副世界地图4 F# W# N! k/ T; c( a4 R" b
import folium' S: g6 p" d5 H# K6 R
import pandas as pd9 y! w/ b: w2 m6 `) O1 [3 P9 ^- v9 F
, N4 [3 R6 ^; _, ?% ^
# define the world map
* e. l8 s& u) \* A7 H+ C% T world_map = folium.Map()6 {$ c# B2 _0 e7 s* x1 X
& V( b0 G n1 G3 V # display world map
, C. @6 E! F, b, P b world_map
9 j( Q9 \ i6 m& N% ?2 M & j+ d+ v4 m. k& E0 J
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
3 o% A- y1 o) Z
# San Francisco latitude and longitude values; ` R5 g( W# _6 M' X2 d E, I- I5 r
latitude = 37.77
1 Y! b; k& p) v: O7 I longitude = -122.42
} ]8 i1 i0 F& G
, k, y, a! R2 p3 \/ R # Create map and display it" x0 I4 x9 M. O- p; X* m' ]
san_map = folium.Map(location=[latitude, longitude], zoom_start=12); F5 G. h& o E
' G/ S; S p: l, g/ G) a# d
# Display the map of San Francisco$ C( f4 H1 a# K$ w; T
san_map
}2 `1 E1 m3 h' ^% K
! ^6 f3 F5 i! f3 A; d, f# i 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
, }" M! D' |+ S' q A: B: b* ] # Create map and display it
, Z: o; n- W# d9 c: l# l san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
" b- \( e, j J# F, O3 o" ` 5 ]. c9 x2 Y% a; @8 h9 x) F4 H, c
3. 读取数据集(旧金山犯罪数据集)
5 P3 H! L: i' t N) Q' f
# Read Dataset
% ]8 }8 K- X2 G cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)7 P; K$ R+ r6 L: D8 g/ R
cdata.head()
0 ~$ ^: `- b* A6 \- c' E4 x# } 9 J0 m; v1 h+ i: y, f( u7 ]
4. 在地图上显示前200条犯罪数据
4 Q& C9 g2 u* o5 i2 _, ^ # get the first 200 crimes in the cdata
0 I$ X! @/ _9 s limit = 200
7 E. q6 N+ O0 [' C& J, h/ B9 n% Y
data = cdata.
iloc[0:limit, :]
: \; W+ q& D( f+ { ^
( s }" ?: T/ |6 W& F
# Instantiate a feature group for the incidents in the dataframe
S$ |6 z9 M, \3 p. k
incidents = folium.map.FeatureGroup()
: G, g* E: I% j6 x) _) ?
) P! B' i1 v8 ^" @3 j
# Loop through the 200 crimes and add each to the incidents feature group
( R% ~/ T* W" u6 ?/ e
for lat, lng, in zip(cdata.Y, data.X):
9 T/ z/ m1 D0 U+ `( b
incidents.add_child(
- \# _# i1 V; e% C! }: n
folium.CircleMarker(
$ Q3 n% c6 D) E4 y% ?# e [lat, lng],
1 M2 E' k; ^! B y+ [# | radius=7, # define how big you want the circle markers to be
6 y1 J+ D$ T) N1 s- ^; l color=yellow,
! P8 I5 w! [1 Q( N0 Q k$ | s; L
fill=True,
- Q7 }8 n% J+ O5 w, M2 V
fill_color=red,
) p( p! u( U& M! j5 M fill_opacity=0.4
( Z3 t f' {: M' _3 T5 M/ T
)
- w4 r% u, Q' T9 L5 y" Q )
( J# x5 w" X6 }9 A3 P4 s# [
4 }; ~: r7 q3 L; Y* F# T1 g # Add incidents to map
5 m; ? P2 |( W+ \( y- e san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
+ @& F# m/ t) X% E0 m& [- h san_
map.add_child(incidents)
?6 u+ o7 f t& `
8 j* H) z& x3 p- t6 k 5. 添加地理标签
3 h, g& v' P' `$ z6 ]
# add pop-up text to each marker on the map
( r& K' H3 O, b+ W5 z8 M3 d/ O. A latitudes = list(data.Y)
- w% a$ S- a' S" B longitudes = list(data.X)
?" h4 D/ ?, t( ]7 C' E
labels = list(data.Category)
9 b# k& O: Q5 J6 A& B: l/ }2 h r5 G: h: S S/ b" R
for lat, lng, label in zip(latitudes, longitudes, labels):
, K" r+ R& M5 L' ]( r! U& i0 Q folium.Marker([lat, lng], popup=label).add_to(
san_map)
3 F. E& j B- q( O0 e1 X- m
6 H7 E* |+ k3 \( H' E3 ?$ B6 [
# add incidents to map
% Z; e' b$ O$ X1 J& p% }9 |9 m$ [ san_map.add_child(incidents)
7 b% S- h/ D0 N# r
- ?( w6 v. k! I% v/ ?' h/ Z
6. 统计区域犯罪总数
6 u3 @0 O- _8 W/ s% u
from folium import plugins
4 q5 o5 E/ p& I/ T
' D: }. e7 j$ R0 Y( S # lets start again with a clean copy of the map of San Francisco
/ _; K& M2 j/ E3 }: S M5 ?$ t
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
- J" ?. e0 }) C* C* s4 b
1 S H% E: P/ A) S( Z B( D4 D# i$ [: X # instantiate a mark cluster object for the incidents in the dataframe
6 Z$ c. e6 h+ l, @4 s8 M- ~
incidents = plugins.MarkerCluster().add_to(san_map)
8 X6 _' J+ o7 g5 }0 y
/ W- j2 @9 m8 T v% u& ?
# loop through the
dataframe and add each data point to the mark cluster
! B- O; A) v1 O for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
9 ]' \% T( H8 b g folium.Marker(
9 Y6 G5 \- i I; y# h/ Y& ` location=[lat, lng],
( l. |3 v% S; }& S3 Y1 j* A8 U5 D; f icon=None,
8 c' a2 p1 O a8 { popup=label,
+ s3 y/ E" B5 }; h ).add_to(incidents)
6 G3 w! |5 k8 ~$ ]: K
- |4 p5 a! }; K8 O$ y2 V/ z # add incidents to map
* g2 o3 W3 J3 K$ p! [3 L
san_map.add_child(incidents)
) z; h) K) v/ P8 z
1 g3 W7 C4 R% K1 t8 A$ |
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
( a2 S E+ D- o/ B5 d! [2 { import json
( q6 m0 T4 ]9 V- p! h0 f import requests V( D* g! F5 F/ h
2 P- a/ @, A5 b# F- t url = https://cocl.us/sanfran_geojson" `1 v- }+ n5 W. B- Y# l% x% O5 \
san_geo = f{url}$ ]# v, X# e+ p0 r3 {% b# ^# k
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
" `4 _3 v. Y O$ f' E v) A2 H+ q folium.GeoJson(4 D# q6 A# k1 H! k( h9 j! v
san_geo,' B# F, q/ k/ Q! G0 D& ]
style_function=lambda feature: {9 [- j7 U B) U( s
fillColor: #ffff00,
7 _$ a1 p9 d' { color: black,
/ P3 m9 h) Q" c3 F I4 \- v weight: 2,
. D4 y- h3 e, B6 i. P& j5 x dashArray: 5, 51 ]( H. C; t; O' [2 i8 c
}
* W# b5 Z% ` R5 T- ~* N0 C ).add_to(san_map) T+ r7 e. g" X3 R0 _& t
A9 y) g1 B; }$ ~! { #display map
5 v; U3 o1 f ~, f9 F* g: K, E) T san_map
8 C, M t- I& o) y
. `. F- ^) ]1 A/ i 8. 统计每个区域的犯罪事件数目
9 J) l) w! H* s# \: V+ P7 q% x # Count crime numbers in each
neighborhood
: P# ^# {* Y) q& d& A+ T disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
! K2 s# g) v! H8 Q0 e
disdata.reset_index(inplace=True)
: f4 ?: C, b* I# z9 j* M I3 Q
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
; R- `/ i3 D; ?3 N disdata
* `; W' F- Y9 Z& U, [0 ~
( Z, @' N* O3 y
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
2 N: R! r( y& C0 T m = folium.Map(location=[37.77, -122.4], zoom_start=12)
T4 {6 N1 Z8 |2 N9 E
folium.Choropleth(
( K& s* a: T. }" X7 S1 r geo_data=san_geo,
9 ]: i0 K: F B M data=disdata,
( s8 U( o0 P1 w
columns=[Neighborhood,Count],
4 k; ?( V. x$ q3 v
key_on=feature.properties.DISTRICT,
- Z* E5 i0 m: x1 w- E; F
#fill_color=red,
0 X. n. j# T6 {, @: p8 Y fill_color=YlOrRd,
& Y1 G4 ]2 Z9 ~# p+ }: O" H fill_opacity=0.7,
M9 y8 T4 G* T2 i7 W/ t/ E e
line_opacity=0.2,
3 p; Q$ u s$ d r, O9 p highlight=True,
. n" b* L0 z( ]' z% |6 k' S" [9 a legend_name=Crime Counts in San Francisco
. G" Z# y% B0 Y& J3 U1 o ).add_to(m)
+ W+ F5 [- E0 I* N, [ m
/ d( S; K7 u! k: q
H" c* W. r- j( d5 s: Q. ^; `8 z
: w1 |2 t |0 z5 B# B, X2 j2 h 10. 创建热力图
$ B5 M: X5 A9 U5 J5 j: W- H
from folium.plugins import HeatMap
/ T5 D1 d; M& a- `. E* d5 G+ u& ~3 M& d" y* ], J. f% W: v& N6 R
# lets start again with a clean copy of the map of San Francisco
5 {/ s6 b2 V( E: \; R2 A" h san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)+ g3 l$ o3 D/ H$ S- I5 R8 u! M
s l: E# `9 J, t6 ]
# Convert data format+ C. L! G4 G, o$ f
heatdata = data[[Y,X]].values.tolist()
8 i; M- h' C2 Z) E
- Z& M1 l# }' @ F+ M # add incidents to map
! G- q Q! H3 e; _( O4 A HeatMap(heatdata).add_to(san_map)
1 ]; o" z: ]6 Q4 C5 J
* S$ X: C4 N; i. V; \* [. _ san_map
' p" Z: Z# o; a! F
0 Q1 L, G/ X! j% e
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
2 Y) \) v3 q0 E. s. [
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
; ~* V7 |/ W5 j" i5 V; F3 Z
" @) f% g) G$ B- u% I( B6 y 我的其他回答:
5 t; M' N2 A0 }' c% ]$ y8 q * m g1 i( _, O/ L
" H7 d8 A8 o8 R 2 [3 {, a1 P: H7 q) a9 y2 w
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
' P' Z. V& b- T! v% A! \# i# [ 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
3 l7 m% _ n! S% R# |) {* [' Z 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
: r7 z& `% b7 c _
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
( l/ p" Y- G3 j" p" a
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
8 ` @& f% C( p8 V2 ^& s4 z l