" @& k/ H3 n0 Z) r8 G
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
3 I. g" D g/ Q$ Y( V 9 `+ w& ]* F, T4 R' y
使用方法很简单,操作如下:
导入包,创建一副世界地图
0 k. S9 W w4 M% l9 U import folium
- r% S; w b+ d _ import pandas as pd& ^+ f, Q+ \: H# S5 F2 _
+ y) B/ k5 k) x% d9 G6 X/ v h% _
# define the world map5 @# q: x; L& V$ w. J v) O
world_map = folium.Map()
* i4 I; B9 B7 g6 _# e( _: z) h# s* R/ E _! W
# display world map
4 ~2 o$ r7 e) x, @$ Y, w4 U" }+ \+ n } world_map
9 N) w& Y1 P9 \9 I F
$ Z' b' j7 K8 x% c 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
! q* ~- i& a; d
# San Francisco latitude and longitude values* w. m: W" G8 x9 ?# V, f
latitude = 37.77
* h: [ s2 A7 S* P longitude = -122.42& Y1 i7 ^- s; z1 v: P" T
5 \2 |0 b: j3 |) M # Create map and display it
7 @9 Y; P0 _/ { san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
' c/ f6 [: B1 D k3 F8 E# t; T- Q) }5 i) t G& R$ ~7 s5 k
# Display the map of San Francisco7 r* F* x/ y5 W( i: t+ j; Z
san_map
$ S+ w" d" i, R4 V+ {3 g8 o2 V) }
2 o+ A: X, y. I4 `/ m4 r. ] 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
# q7 n) Q% K* o: _ v5 {
# Create map and display it
# w4 W: \) t7 j4 c) f san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
. g O- k' {- d' _- ~* e 0 O% G ^$ b+ X
3. 读取数据集(旧金山犯罪数据集)
! _/ K3 c5 i# {' y4 e1 [
# Read Dataset
`6 w( {3 W! p m3 \ cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset). l) @, `2 C u ]5 |3 A
cdata.head()
1 n5 H8 E3 D& a3 P, d
( R* a. N+ C K( j' n1 E! x: i
4. 在地图上显示前200条犯罪数据
; ?& j4 G3 [$ q2 t8 ^3 A8 d # get the first 200 crimes in the cdata
5 U% D" G. I! S0 J3 G+ j' H& f% K limit = 200
b# n$ u$ E% ?/ ~' l0 ~" v
data = cdata.
iloc[0:limit, :]
+ y% U% q" [- w7 `
" N! H. P. K5 b8 Z8 S& f # Instantiate a feature group for the incidents in the dataframe
+ B' P' t; f% y8 `. V. {1 S3 {! U
incidents = folium.map.FeatureGroup()
2 U/ [& i* ~/ X6 O+ I
8 N' Y, Q& K! a$ G4 T+ u7 y6 L # Loop through the 200 crimes and add each to the incidents feature group
f0 l" q+ i1 d# K# R, a ]6 M for lat, lng, in zip(cdata.Y, data.X):
. m ~& k; e6 j% ?2 P. e incidents.add_child(
! {+ l* o; ~9 ]# | folium.CircleMarker(
6 |0 F" a; V# L( w# e( { [lat, lng],
4 @* y& P8 J. R; A+ p
radius=7, # define how big you want the circle markers to be
5 q, t4 E4 X( {4 t7 Z/ g
color=yellow,
$ b2 e ]1 B. E fill=True,
) J$ z. y. t3 ~* g5 l* C
fill_color=red,
& A; D. I8 z& K; t4 @1 V& e m
fill_opacity=0.4
# [1 |8 N- V+ h4 ]- h )
8 J5 @3 u1 A" m% f
)
# j( ?6 D8 {2 |! M9 q. C6 g
& S( C; j1 k) \' R& `( X4 I # Add incidents to map
) Y H R; o! {" [1 f san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
n2 G0 b+ e9 i( \# e# Q! Z E* O
san_
map.add_child(incidents)
% f% J% ]9 Z7 Q x* ]3 P
: G0 k5 W" M, \. R2 e4 O; N 5. 添加地理标签
) x6 \$ b8 N6 c, s {' R # add pop-up text to each marker on the map
|; [" I' [* U: V8 b& o6 n1 a
latitudes = list(data.Y)
' A2 ?' Y: I/ P% R" `- P0 a1 X' Y9 C longitudes = list(data.X)
# R( Z4 h: W8 _4 J) W9 ~
labels = list(data.Category)
% b; a% k; c7 Z8 ^4 d9 L; B. ~0 u2 K4 _. E c- P% E* q" ]
for lat, lng, label in zip(latitudes, longitudes, labels):
5 D- s7 ]+ f: U9 l; k+ [- l folium.Marker([lat, lng], popup=label).add_to(
san_map)
3 x( a9 S! x' b0 H+ a9 p$ W0 O- c9 _: X, q8 k ?. l
# add incidents to map
+ j1 z# l5 Y# ~5 E& D
san_map.add_child(incidents)
+ O' m7 g- C3 r9 c2 `! y
T \0 [: l7 ^# U A 6. 统计区域犯罪总数
c8 P: G% `9 e, G( x% R
from folium import plugins
1 O' L' t% j4 ^/ B! Z# C- L
( T/ w. C- K* A" \' \8 o # lets start again with a clean copy of the map of San Francisco
1 z% F% v2 G$ N+ l8 F san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
) M9 f& p" Q( f6 M! p
5 m7 T! k' c! x0 ? # instantiate a mark cluster object for the incidents in the dataframe
! A; L5 Z" S; b5 n2 d
incidents = plugins.MarkerCluster().add_to(san_map)
5 T1 A3 l9 v+ Q
% l9 L( p, w5 u" r # loop through the
dataframe and add each data point to the mark cluster
6 s+ _; C! t, {% H for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
3 n9 O, O9 j6 G: t7 f
folium.Marker(
+ H. v, N% i% K; u location=[lat, lng],
" J& ~4 n; Y( x) R' y
icon=None,
! i6 l9 m0 F) M, n- ? popup=label,
, Z6 C g& w8 [# ~ ).add_to(incidents)
( |3 T& B: t$ m. ]% V2 A! Q1 o% f- b; A {( l
# add incidents to map
; B$ g% B2 }& l4 e5 t' D san_map.add_child(incidents)
, v- |3 A+ Q Y% i$ }
9 { y- i+ w" {% V8 T 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
* o1 ]* }0 |' _0 K' g import json
; K8 |0 e3 d E$ D6 Z6 Y import requests5 k& [$ ~( t% _* g8 y
+ A& d1 s" ]2 J% u" r
url = https://cocl.us/sanfran_geojson5 p7 A2 g! @8 X/ i9 ^
san_geo = f{url}
9 f! ~+ @' J* `2 k san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
/ s0 ]0 V/ y- ]" A9 i folium.GeoJson(
' g" E3 p! f5 [! J) Q+ ?* b san_geo,& M8 l4 G; p% S! T
style_function=lambda feature: {% P& o& C% m" U* [; ~
fillColor: #ffff00,
$ X( W3 @/ X2 z8 d: {, [ color: black,
! ]- Q2 Y2 V( y; g: o weight: 2,3 @( S+ q7 E% x
dashArray: 5, 5* J" b! z c: M" ~. W2 w
}+ H$ l7 _* q0 I: x% m
).add_to(san_map)
/ d7 K% l; u$ J. P8 G/ a6 T
+ ?* N) F$ x. Q8 M1 [6 O7 z #display map! t' ~% g/ _& e% F
san_map
% U* v8 I6 q5 L2 N! }$ U( ] ( B* H$ m7 J% q" k3 c0 K
8. 统计每个区域的犯罪事件数目
/ X# r1 m( h" K: {; G$ J( I* m # Count crime numbers in each
neighborhood
. o$ m f2 d/ ?' e/ W: ^/ y1 ]6 e disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
+ V, F3 z' ^' K' l ]0 S disdata.reset_index(inplace=True)
# ~% R: \4 ]+ ]+ S' v( @
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
) S. H! J+ @& X3 q8 i, ]5 Z1 h
disdata
' |4 h0 v# c$ O1 n" C& K8 y
+ d* b$ ~% Y# f. g" d8 m( s
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
5 X9 c! E3 D2 t1 ~& M0 P5 C m = folium.Map(location=[37.77, -122.4], zoom_start=12)
# l( s( Z& w' t" {
folium.Choropleth(
/ U! K5 L' k; X Q5 p' I
geo_data=san_geo,
3 o1 Y- L9 l( c" B' Y- B data=disdata,
$ |/ ?2 W/ C% Z/ k) T
columns=[Neighborhood,Count],
3 i' p4 \$ {0 d* ` key_on=feature.properties.DISTRICT,
# S6 |$ v* X' G6 ~
#fill_color=red,
! k4 Q, @' L3 w; \* ?
fill_color=YlOrRd,
- a$ n. j, r3 S$ f
fill_opacity=0.7,
. M! d0 X' v& ~) a$ _ line_opacity=0.2,
+ j8 O! v' Z+ @1 O; F
highlight=True,
, ~3 t2 x/ j( K1 s, k; r& m& `& l
legend_name=Crime Counts in San Francisco
! x5 o6 c# n3 t! p7 u8 }
).add_to(m)
. E( l# n- @, ^( N- Y: w
m
8 o3 {1 {3 e5 ^- F2 H# }
6 i2 y# S, w' j6 k# z6 H# z 8 ?4 N% Y9 L& b1 k9 J4 `
10. 创建热力图
& I7 ?( i$ J6 M
from folium.plugins import HeatMap& C- c* b$ _8 J# O
+ J& g n2 d) c* g/ z& V4 S # lets start again with a clean copy of the map of San Francisco
5 Y. L1 J2 Q$ k+ ~) R san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)! L# h( q; ^, H0 i5 p+ M. I1 n
~6 n% k9 z0 r4 C4 N! K4 o # Convert data format7 V- x2 F6 }6 e' y6 }3 \8 B
heatdata = data[[Y,X]].values.tolist()
; n0 h; x1 ]$ A& @$ ?; X1 s( G8 R6 k+ H
# add incidents to map
9 ^( A9 r1 _9 }6 ^, q: J HeatMap(heatdata).add_to(san_map)
0 f. [ [3 x! A3 p; L/ ~1 b+ u; l3 m9 w0 f$ Q- I: q! M; F
san_map
* v0 c% j( j/ U b8 Z 0 l* M- E$ \$ ^; r+ F6 w/ w
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
* `& ^8 z& J) J9 Z 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
- W7 C4 ^8 Y; }9 n
3 c+ @0 N: C+ M9 Y% V7 A. S
我的其他回答:
% U! L$ H, m: c. |+ g& ?+ ` ) `5 a( Z7 I1 i+ l2 i6 R
) i$ D. D& w* Q! q& n
3 e3 ]* N: n2 [! V+ [0 ^6 [% j4 d
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
- f0 y4 l% s1 ~; C7 ?! N# |
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
2 [5 l: h$ l$ p; E1 b- \
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
: S3 W! E, U5 n+ y, b 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
" g G0 H! n+ D3 K# f2 J0 w
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
8 V. ?7 J: F, ^$ O3 F: L: b: X+ k