3 b2 i2 u; r$ T. V% ]1 _: v
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
$ y8 ^7 u$ _8 m! O$ k
3 b( K& u( B: p3 Q& e) |- J4 R 使用方法很简单,操作如下:
导入包,创建一副世界地图
: n0 v+ c. T1 m import folium& ]- c% O; H; `# g: f+ f
import pandas as pd
" w& @: S) _) _( |! }% @- r* @5 n" [1 Z* O2 y) P' [1 `
# define the world map" M8 ~- s4 }- P# l4 d& ?4 |
world_map = folium.Map()
4 m7 x, C( E$ _6 {9 y
6 w) H, A8 a+ H+ I0 O/ |" N } # display world map b9 H, ^6 [ F- J/ Z1 ]
world_map
& _% J* H- u) q. H9 u: e
' b, [: C0 d- V
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
# D, g' K- I, s6 D/ f; a$ d7 Y # San Francisco latitude and longitude values+ J! K& B; L- j* }- @# l" r
latitude = 37.77* M# a' J. ?) N# a
longitude = -122.42
4 F$ I, e( w8 E* v/ h
% Z+ `- U+ m1 P( m9 L* v5 @ # Create map and display it# J2 ?# }3 @* o) r
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)9 n e! T) l8 J$ V* _
2 b+ c2 Q W* g& u ~
# Display the map of San Francisco
+ j6 C- y# b! q" u6 M0 n: N$ n san_map
/ ~2 A; X& _& W, ]& ?
4 `# S( e; B& ?6 ~* i) Z1 f
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
{4 X: g+ S0 y& H2 U v # Create map and display it
! v8 f' o8 h) l2 _ san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
- H- E* h o; M5 w: o! U X/ _( _
! {9 ], [" k- Y) }2 x6 ]$ }2 u0 _0 Q
3. 读取数据集(旧金山犯罪数据集)
, j# _/ r& m8 z d9 L
# Read Dataset+ w# ~$ ~4 E: x7 p0 o, n& ?
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)7 K! [7 Z* [2 ~3 V( ^& `
cdata.head()
# z" w' \0 e$ y( v! [
& @+ ?9 d5 B# p 4. 在地图上显示前200条犯罪数据
8 W3 v& e; ]- x R # get the first 200 crimes in the cdata
9 S4 Q+ {: h1 a. V limit = 200
% k, c, s& X3 J8 Q2 G7 ~ data = cdata.
iloc[0:limit, :]
+ H2 v. r& w2 B$ w4 e# V
2 h8 f+ O5 o" Y- F. e& ~) } @ # Instantiate a feature group for the incidents in the dataframe
9 X. I. R( T( `9 g' ? incidents = folium.map.FeatureGroup()
5 f2 B$ ]! k) S) a: z! Y5 Z: w
' |0 P. `' y, a* [8 p8 o # Loop through the 200 crimes and add each to the incidents feature group
9 U9 e0 K7 b U* Q" H e
for lat, lng, in zip(cdata.Y, data.X):
3 z8 n& |7 M: `4 c$ y% C9 i+ g9 k incidents.add_child(
9 Q4 ~6 y8 K' z( A8 D
folium.CircleMarker(
v2 {" `5 ~5 t% K [lat, lng],
+ w' O' m. D# h
radius=7, # define how big you want the circle markers to be
! c+ F. T& J+ _5 J
color=yellow,
9 {+ ^. S( d" X8 t" g fill=True,
4 g& y/ T6 U8 M2 z' Z- k
fill_color=red,
" R8 _' {* c+ o9 M1 Q" q- U fill_opacity=0.4
: @5 w R, u# l" `* ]$ p0 l- a )
' U) k& G, H! [) ^1 i
)
9 T7 U" b0 E& c$ x, Z7 T8 y
5 P& D7 i7 Z( i # Add incidents to map
9 N* \ e. e- Y p! `3 ~ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
, ~/ i- y: O" v+ C. N0 p, e
san_
map.add_child(incidents)
; j, F' @4 Z: V% h0 U, y& Z
/ h/ n, E8 \6 L' i7 m! U: g7 O6 E
5. 添加地理标签
k' V: y6 \% ^0 {2 V
# add pop-up text to each marker on the map
$ \% h( g. C4 d# g; W! m
latitudes = list(data.Y)
/ d) v! e* J8 u* O! {, @$ ~& G longitudes = list(data.X)
' \$ J0 T1 h( p5 b0 E6 A labels = list(data.Category)
7 Q8 P3 g7 [) W3 X) f* a' e. ]
& |) f' `. U, v7 E/ L" a: S* i# x& [ for lat, lng, label in zip(latitudes, longitudes, labels):
& C8 Y/ ^% e2 o* G0 o5 s( B folium.Marker([lat, lng], popup=label).add_to(
san_map)
8 F. S1 V, D8 r9 Z: u# F0 {( ]3 b' w
# add incidents to map
$ L2 O; S; T8 a( g. w; _1 i3 M( S san_map.add_child(incidents)
9 e3 k5 s0 B4 u( F
2 ]. Y4 f- |( K s/ m8 h: K9 L 6. 统计区域犯罪总数
6 H g3 r4 ?2 X
from folium import plugins
1 h2 |; ]6 w" Z8 O _% f
9 D7 |* Z+ b# M( P9 z. b # lets start again with a clean copy of the map of San Francisco
" U/ T, w, Y' q7 A+ v san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
+ K9 o; Y4 B3 h, ?
9 ~, \ T) m- ?' }5 m: ^, R- \ # instantiate a mark cluster object for the incidents in the dataframe
1 B# C5 K* V, e* i- h
incidents = plugins.MarkerCluster().add_to(san_map)
: X; \1 I5 Y4 G
2 Y' r9 U$ H' D2 Y2 h2 ? # loop through the
dataframe and add each data point to the mark cluster
7 O6 [1 F, I: W0 `! p for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
) H$ c' ]" d( S( J- J% T folium.Marker(
* T' Y( S/ @# S# c7 o2 r location=[lat, lng],
8 u' j9 b; h3 v% m$ p& U icon=None,
7 n! t8 u3 Q4 V0 m/ l$ ?& p' s
popup=label,
- t8 I+ A4 N$ @1 C3 p" C8 r
).add_to(incidents)
* R7 h6 Z3 p# O+ Z' b& z7 L! e: n. c& w x) a9 X3 `
# add incidents to map
9 N) [4 v/ g2 v" n/ x) a
san_map.add_child(incidents)
" I; z" C- F* D: j
- v' H% O( D2 U8 \
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
; _0 E! g9 q2 b9 N" D H import json9 s/ A9 Y+ y# G3 {6 G1 t1 g
import requests0 d/ d& Y/ @% ^& y
# h+ E: i% Y0 z* z; Q url = https://cocl.us/sanfran_geojson& L& a. f7 z8 L e7 X/ n8 ~
san_geo = f{url}
; m% Z# q! L' n: z% J8 T+ p$ m: ]9 W san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)6 h+ C" M: C6 V8 a5 I4 r: R+ R7 T
folium.GeoJson(
/ q) i0 M0 R7 K& u; v san_geo,
9 L; v5 C5 a0 x style_function=lambda feature: {
; C* f' N G- v9 O) {, F7 v9 { fillColor: #ffff00,* U3 h( c6 Y- r3 \" H B3 k! L) |
color: black,# e" k7 P5 |8 q3 w' U+ `, o
weight: 2,6 y/ C& G6 S( ~" q. k( E
dashArray: 5, 5# ~9 G$ X5 H- n: k1 M1 b
} a F4 B& N% z( o" s( n
).add_to(san_map)
$ ~7 S- n7 ^" S
/ [2 z* P6 }5 B, y* U #display map2 T, `1 t8 [- k* J
san_map
+ e( L8 D8 h" k$ Z; r
1 G4 a/ I2 i' T" {. r- l: t5 H. { 8. 统计每个区域的犯罪事件数目
/ Y3 o1 B) D7 H2 L0 D: _/ n. J
# Count crime numbers in each
neighborhood
- }: s; \( Y/ G5 L1 @) p, B( I; v7 U disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
/ B: O; a$ W$ k! l) V( z disdata.reset_index(inplace=True)
0 K& U9 L1 R, K5 S& p! {- H) e
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
: E: u* S9 N- }; {& B7 T disdata
4 d c1 ^& ?0 d: W ! x) t( I9 V% L! ^; d* d9 ~
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
% h% Y: ^1 O" e+ J4 p m = folium.Map(location=[37.77, -122.4], zoom_start=12)
1 s/ x0 Y, J e1 N* j
folium.Choropleth(
! `! K v' K' @ geo_data=san_geo,
. g& `8 c, \7 J+ R% ^
data=disdata,
0 c( C2 c2 j2 K6 c3 I1 w" H
columns=[Neighborhood,Count],
. g. N( |4 w2 r' t4 \5 ?9 J) M
key_on=feature.properties.DISTRICT,
/ G9 m V, w# \ #fill_color=red,
& x8 ^* _$ y, Z! Z1 V2 @- d3 A fill_color=YlOrRd,
& @& O' B0 C, V8 V" w5 F0 }
fill_opacity=0.7,
( b9 j( @4 J/ M& Q0 A$ d* d1 }
line_opacity=0.2,
# f% r5 S8 u" C4 R highlight=True,
! o u( u' _" J3 D# x3 S
legend_name=Crime Counts in San Francisco
9 k/ v" K; n) ]& ~) ?2 q
).add_to(m)
# g' ]$ c# X+ b6 ]
m
% r9 l( ~. M1 G6 r7 k# U! r) g( Q
$ X" ] g0 n4 B" x) M" H) n' U # u9 a" J$ G. v$ |$ u0 Z
10. 创建热力图
$ v/ a' v! v4 u! r, T2 H$ Q$ s; ^ from folium.plugins import HeatMap0 D& \+ ~7 t( v' k; e
# p# m! B7 f; x7 [) e+ F
# lets start again with a clean copy of the map of San Francisco3 ~, l( j+ a3 t3 Y# E. N
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
: b; n- Q* r# {9 ~- r) o4 \6 Q/ u1 p; c7 w9 {
# Convert data format2 d0 o' A; h7 Q: S
heatdata = data[[Y,X]].values.tolist()
# l- P7 j# X: E7 x% F( B" a( G2 K8 w# \, o& O
# add incidents to map: B v# H. m% v' A
HeatMap(heatdata).add_to(san_map)
# {" f& u$ D+ x! ] ]2 [' l( d7 H) g. Q6 E' r* F3 e, V
san_map
$ B: d. e. `) b5 H
: M4 t/ Q, S G& W
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
- m$ U! W2 K4 g+ G# _
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
0 s6 Y; u& y1 D& S
" E; t. W9 a [, `6 w 我的其他回答:
& S. _( \9 _" W& d
0 t- V k0 S1 v- H' k! f6 N 4 j0 {* C+ ^( M, _' i: L- S; L
9 m3 Y. @ K) I+ X7 E# {6 P 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
! M! w% l- A/ ~, I; a 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
; @( W; ^7 G+ i2 f3 E! m 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
" o- f6 E; S z3 R: T/ v 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
% S" H* W- E" _* R 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
7 N8 ~/ R/ `$ R, k8 _; n- T5 \' }3 J