7 h8 A; Z. Z. U2 m; E4 E' C, r8 ~
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
' M+ L- B7 `+ M2 B2 J) R' P% T
5 ?# `8 G0 @3 T2 W
使用方法很简单,操作如下:
导入包,创建一副世界地图! [4 o% U: p& W& x* A m0 V
import folium
% u0 Q t* |9 T* v9 n! ~ import pandas as pd
: v0 e1 ]# [! A, a
: o; C4 C+ F, m- |" [ # define the world map
) [# t# ~" \3 i8 }0 D3 K; m world_map = folium.Map()5 N( ^( @; |6 O# ?( T- g8 H4 E q
/ f# L4 l' _1 u/ E3 o2 {
# display world map! y2 \9 z( A; [7 @
world_map
; K) O$ n+ y& w $ L. L- ?+ x( |0 O5 B' d& {+ k- ~, L% [
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
0 Y. o. `0 A' g: S* W9 | # San Francisco latitude and longitude values4 A8 V$ A/ o v) Z/ v9 [4 g$ H6 n
latitude = 37.77
3 G) `7 e1 [& A3 Z9 m' \$ l+ m longitude = -122.42
3 R, O1 r& o& y0 ^" x
$ Q* O2 u ^3 ]+ q4 C) J # Create map and display it
6 U6 j$ U4 ?: S2 a2 S san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
9 ?5 W$ v$ P" g5 C& V) D4 w( f1 d' H# [+ f! M! a1 P
# Display the map of San Francisco
- Q( }: O/ W3 q9 r6 @ san_map
: i9 e0 j7 Y- K$ c
& k0 K& _- N$ L9 e/ w0 I5 N
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
& x: e) y9 r- j0 s6 I: ?9 R
# Create map and display it
, R" d+ c* Z! Y+ {8 g san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
* C i: m! e, n/ J7 q
+ O! ?$ |( f a2 M& O: W
3. 读取数据集(旧金山犯罪数据集)
1 v, X: g+ x/ x5 } # Read Dataset3 e) d( D5 q" c3 I- ]
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
( R5 S# s% J4 i; k cdata.head()
9 n# u3 ?7 c g8 Y' j . _1 P3 i# w: o6 ]9 ]
4. 在地图上显示前200条犯罪数据
- F1 v; z% O# P( T/ n
# get the first 200 crimes in the cdata
0 H- W; Z1 R# W$ J* n6 Q) x
limit = 200
9 B) Y- c( b6 t# h' j4 } data = cdata.
iloc[0:limit, :]
6 t f$ g) K" c4 I+ X" Q
2 S1 E- a) S! b/ g3 E* O1 C8 t0 [ # Instantiate a feature group for the incidents in the dataframe
+ t/ m6 l9 |5 o$ h# C* |
incidents = folium.map.FeatureGroup()
8 X \8 [5 W# Q* A) H
+ y7 `& M6 A0 V8 @8 q # Loop through the 200 crimes and add each to the incidents feature group
5 Q" W8 K/ ^+ B' Y
for lat, lng, in zip(cdata.Y, data.X):
) r( H6 F! p9 g" _
incidents.add_child(
4 p3 C9 ?/ g/ X5 ?' U folium.CircleMarker(
9 S4 s" u' U3 T" ^- ` [lat, lng],
7 V/ p6 m" [6 X
radius=7, # define how big you want the circle markers to be
# C( x W- j6 I7 A' ^2 x: p color=yellow,
) a6 }. f( h3 E3 p) X fill=True,
( V6 u9 H' W7 [! M3 [/ S$ b fill_color=red,
# Y# ]/ P( B- T' N- d( | fill_opacity=0.4
, L" \5 f6 N3 z3 u, T- Y )
% f# O; [2 v4 m) e )
Z' H" Y- n- s$ E, c e) t/ S, U; [/ `/ b# N% m( n
# Add incidents to map
; u" |! G. {; S6 |8 l7 C
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
N- O5 y6 [0 m6 m0 C san_
map.add_child(incidents)
/ a8 a- D4 a9 v
1 _( C h# C; n# z0 o& j 5. 添加地理标签
q8 K* Y) k+ r# S; y
# add pop-up text to each marker on the map
}6 g4 `) K$ M! l6 C latitudes = list(data.Y)
: }$ J& X% O9 w/ F3 R longitudes = list(data.X)
8 M+ f- _* f+ g: o( G: u/ p( E
labels = list(data.Category)
0 b ^/ m( T, J$ m4 u4 B3 |( I* ~1 k" h: G2 A$ s
for lat, lng, label in zip(latitudes, longitudes, labels):
$ [: @; H' T# m+ U: {, R" r folium.Marker([lat, lng], popup=label).add_to(
san_map)
! u# n; B" y+ ~+ P0 O- `$ {/ ?2 R9 u4 x8 X0 v2 H# T4 A8 P
# add incidents to map
2 V: |3 \7 X* \8 x4 |- Y
san_map.add_child(incidents)
: k, M% M6 G# u5 {9 W; ?
9 O7 G/ n3 t3 u* h 6. 统计区域犯罪总数
% h8 V& k* H e! c) [9 M: O from folium import plugins
9 i* N, L3 ]0 [1 g" c" `# ^
9 A' ?9 t- P, h2 b/ i" | # lets start again with a clean copy of the map of San Francisco
4 N ~( N& F) ~8 _+ W% B
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
8 O& d0 G* u1 |; G
3 ^# Y$ m s6 K. `) w# k
# instantiate a mark cluster object for the incidents in the dataframe
7 K" g+ `) A+ B7 M
incidents = plugins.MarkerCluster().add_to(san_map)
/ S2 Y; r9 t7 E5 l1 m h; N
# e6 ^$ I( C- ?& i* U # loop through the
dataframe and add each data point to the mark cluster
0 z, o3 n3 l9 p9 d( o( l$ V/ P
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
8 ]0 O5 n" I& O$ b$ v folium.Marker(
. Q! \9 }1 \- n! ~. l
location=[lat, lng],
- H, P, u( @6 Q/ u+ }1 k
icon=None,
5 j; L' z! B O& D, [ popup=label,
* l: y$ v* w/ i- ^9 K* X ).add_to(incidents)
. K+ t6 |% ?4 ^; l( N4 [9 k- H; [- I1 m1 M
# add incidents to map
; L, G% _, j2 d$ X9 I3 O san_map.add_child(incidents)
* R. N+ N7 G. v, W! X* w, }
z* @2 T p% i! B5 }5 w$ g 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
( t% S6 d0 S) H5 j6 D! w, c7 V) F
import json4 ?* p* K3 i- ?$ M" j. V
import requests) [8 n6 l) T7 o7 I g
3 b! Q5 {2 u3 I- t+ d2 N url = https://cocl.us/sanfran_geojson
5 S# w6 d9 s8 O4 X san_geo = f{url}
: e: J/ W2 Y$ Y# r san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)0 ^1 F/ R* l; l6 m
folium.GeoJson(
8 B3 ~7 }6 ` C' w3 `% D- L2 Y8 W san_geo,
; b' K3 e- X4 l/ d! \ style_function=lambda feature: {
: |$ W) D: f' u fillColor: #ffff00,4 E+ Y1 X6 m* ?; g* C) k& o
color: black,# K: S7 g/ y, C* Q& h' k
weight: 2,) I; ^7 h& r) ^# l. r
dashArray: 5, 5& W0 U4 M" w* {1 C
}7 t7 n- u7 a2 U2 L& e
).add_to(san_map)
# @+ B: f# f* k- {+ V8 |1 ]$ A4 x4 r, Z0 q
#display map
; V( v- _' e4 Z: v% F6 u, ~ san_map
: |* b% \# c+ s- \
4 y8 y5 A- ^; C0 }# b! ^
8. 统计每个区域的犯罪事件数目
0 x" X9 y, H3 }3 [2 ~ # Count crime numbers in each
neighborhood3 Z( q( o; `- R
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
# r! r3 r( _6 x' ~/ H
disdata.reset_index(inplace=True)
" _. ~) w; B$ C3 H
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
1 O( v0 }& [$ o1 n* l* P
disdata
9 _" r. K# f2 c7 Q9 z6 G
6 Z- K K6 J3 y% q0 h: g6 w. V5 m
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
4 }$ f K: a+ Q1 X) T m = folium.Map(location=[37.77, -122.4], zoom_start=12)
: ~2 ~( p4 R9 T! }7 @$ g
folium.Choropleth(
% e- s7 n" P# ^: Y* I6 L ~
geo_data=san_geo,
( C0 y; n5 A; S( e data=disdata,
2 V' L8 } D, c; f/ V9 S
columns=[Neighborhood,Count],
3 a, P/ B. U' w$ O
key_on=feature.properties.DISTRICT,
7 K1 o4 P1 b; H/ }0 H
#fill_color=red,
; S+ c" z6 X# k% a# ]8 h9 P
fill_color=YlOrRd,
0 J+ A& B7 B6 {/ d
fill_opacity=0.7,
2 H2 q3 ]3 Q" B
line_opacity=0.2,
# r" N L. _0 s2 a) _ highlight=True,
- ?; N1 j& ~; g! S# \. o legend_name=Crime Counts in San Francisco
) h T1 D+ ^$ j6 o' a6 E" j5 ^
).add_to(m)
& W8 H" _9 {4 d1 p+ U# k
m
; h- X6 d2 D# P 1 O8 Y, P9 K3 n( B& V' S% Y* x
, U9 F3 A2 d, L; c4 Y
10. 创建热力图
$ }# j- d3 }8 Y3 A5 R A ` from folium.plugins import HeatMap4 A& M6 `/ j1 D8 F6 V4 o a( q- e
% c' X4 h0 D1 y: u& t # lets start again with a clean copy of the map of San Francisco% W8 T- b$ x4 n" r3 N
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
* \! K8 x5 }* J$ ^) X
: J7 p: F9 a% V3 N # Convert data format* [$ C% F3 {) s2 l
heatdata = data[[Y,X]].values.tolist()( D6 ?2 h! X' I3 ?: b) s6 S
! Q) v1 X9 j0 G0 Y8 D
# add incidents to map
. h: Z k, g! ?! r) `9 e! d HeatMap(heatdata).add_to(san_map)
* e9 H5 D$ X: k8 T/ K6 A5 w
/ L/ \& w* n. ]3 g+ w san_map
# |+ c! ]* u3 K k' x- a 1 i2 l( ~! k' H7 U
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
! I1 s- E6 P" j$ T: w" q 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
- c+ e \" W0 V1 Y9 J9 o& p 6 _& d; M6 I' k9 ]* {3 c4 @7 c
我的其他回答:
6 R6 j" v y2 l% L9 t
/ }8 t% d+ T3 I- e9 _6 z $ W3 ~, y- D8 d/ H
) ?* `# t7 h" i$ l' i 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
, o6 N! O- T$ z7 `: x2 @+ W+ E. a# e
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
7 A: T' p" x1 Z+ S4 j
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
7 L2 R8 @" G6 g5 e6 Q 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
7 c8 ^( O7 [6 W! s9 ?, C
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
4 @- d5 v( K4 o8 i