1 M% V. b+ y u: I$ {) [$ l
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
0 N f( w, K0 [$ N' S # w' G0 ]/ |0 J, X+ d1 q
使用方法很简单,操作如下:
导入包,创建一副世界地图
- \5 f0 L! |/ q import folium
( ]/ A$ d* E7 ]5 w$ O: a import pandas as pd
6 @% a [* i4 F* ~ v. @" x4 ?1 s g. E# d3 E: u" j
# define the world map
' i3 }, z/ I' P+ _ world_map = folium.Map()
* y1 [' A6 Z2 I$ T' p8 D R- s- Z" H7 f
# display world map$ V2 _* K- J V1 u: O
world_map
: a5 w/ `: k1 w3 j
" Y8 @# o- c& f/ B% H 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
4 j% u, c) g @% q5 i, ]& g3 n
# San Francisco latitude and longitude values
2 @/ y* ^" |8 {( J, z% L latitude = 37.77
, Q! i* n+ }! I3 l longitude = -122.42
) A& q* J& f1 G9 x4 S8 O: {* x- b+ ~ B+ @
# Create map and display it) [8 R& N: o6 l) ~% I% A
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
, B8 _8 z2 p, n/ k7 C/ i5 R8 x* ?: I
# Display the map of San Francisco
0 i5 v5 V. s. O% h4 f san_map
9 e9 G8 @7 u$ G0 e8 X
7 c& ^/ o/ w6 r 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
: t2 }7 m" [; r # Create map and display it
. L7 Z+ v' M( U5 r( R; h san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) t, } u! X4 I3 `& K: n' s
" r# @5 F2 e* p7 _- p0 X
3. 读取数据集(旧金山犯罪数据集)
. Q3 a/ d4 v7 D0 S
# Read Dataset
; b9 [& [8 o; [6 N" b9 \/ Q; N8 k cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
9 }9 a4 V# D+ y( e+ a7 f4 @5 N cdata.head()
2 |1 b# c" q! a8 _+ e1 a: w5 W% x
) m( v( Q$ @7 T% Q2 j( {: e( ]& Z3 I 4. 在地图上显示前200条犯罪数据
9 O( E7 c0 s* ]/ d* j" V # get the first 200 crimes in the cdata
& r$ w) W4 z2 E B k) _ limit = 200
5 f7 n7 Z+ u/ S+ a5 z data = cdata.
iloc[0:limit, :]
9 u2 U7 l: z# [& C; A$ W
7 R/ j% f. U1 i; P8 \+ | # Instantiate a feature group for the incidents in the dataframe
" ?9 _, X6 `1 x2 v- W6 U incidents = folium.map.FeatureGroup()
3 ^% j# X# g8 g$ W6 c6 e1 K) d
. k3 M+ |7 v: Y+ } Y9 N # Loop through the 200 crimes and add each to the incidents feature group
) D) X3 G1 }# i$ p4 r k
for lat, lng, in zip(cdata.Y, data.X):
2 O. q; i _, h! ^3 M6 k* Q
incidents.add_child(
- U" J# m/ h, ~, ?9 ]9 M) x
folium.CircleMarker(
" _% w' q' M5 _ f9 s3 U- A
[lat, lng],
, [) N. b; b3 N: V5 i% K" p radius=7, # define how big you want the circle markers to be
! U6 J, I3 ]/ D9 U# h( N
color=yellow,
" w; z- t+ ]9 {, Y7 ^( o. H+ Z& ?
fill=True,
' p7 e# J6 F& E; x z4 a fill_color=red,
2 d3 R q; X; g fill_opacity=0.4
1 q( v7 n3 Q# @9 z" l. l6 k
)
% i, M9 y" k* R! o* q3 W' _+ q f )
' J' q/ p. E. X) _3 p4 Y
2 h9 [& w# W8 M3 _% F3 k9 s; }
# Add incidents to map
6 p) i# m' t9 g4 _6 I, m
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
5 H& Z: X, K# z* S san_
map.add_child(incidents)
& M2 L$ R$ ?, K1 M* l. R$ N
7 V- L4 `6 R, h+ J# B
5. 添加地理标签
- _1 c: X" q5 w7 l0 D
# add pop-up text to each marker on the map
+ P2 Q; B6 q+ z3 v9 y- R+ x latitudes = list(data.Y)
; s( s- I9 I, H longitudes = list(data.X)
. }* [; L. K9 a& ~7 M
labels = list(data.Category)
* q6 l& t6 Q. {0 Z3 j9 ?; B: V) E' y- u* c
for lat, lng, label in zip(latitudes, longitudes, labels):
8 {* Z) R& u2 U1 S0 ^2 x9 I0 P8 O/ w
folium.Marker([lat, lng], popup=label).add_to(
san_map)
$ e- v2 H# ?6 n$ ]
# s6 ~( k8 Z9 \1 }
# add incidents to map
; |6 j2 v( `, N- H7 X! v6 W" d% J
san_map.add_child(incidents)
6 z' v. A; E& @7 t: d
?3 z. f( w7 U7 J' R; I/ p
6. 统计区域犯罪总数
" O: t+ l: q3 g U, R2 ? from folium import plugins
0 d+ |& Q+ W' Y, ?5 F4 K( ^2 r) T1 V2 `
# lets start again with a clean copy of the map of San Francisco
' L2 w- v; g, b4 z& f, Q, w
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
) s* P4 Q V& z" Z, E: [0 y- z% l* E& |
# instantiate a mark cluster object for the incidents in the dataframe
) }4 b7 A9 L h2 [7 ^+ G8 I
incidents = plugins.MarkerCluster().add_to(san_map)
4 p9 P/ f8 g N
/ e) W0 N# T. h! W8 n # loop through the
dataframe and add each data point to the mark cluster
6 {2 [' v) }# v for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
* N, T) v& a: K* B1 ~4 D$ h- K7 y
folium.Marker(
3 U% K; h) W% e4 p3 K location=[lat, lng],
+ ^! A. Z, N% g! D
icon=None,
2 n8 F) R+ y: m! s; |+ R popup=label,
6 C% W2 f. V6 u6 o. W
).add_to(incidents)
# [9 t5 z6 s" j8 H# x
/ ?) \" ^3 f8 g @- E" H # add incidents to map
& j4 H; P/ V$ H' I
san_map.add_child(incidents)
" ]+ L" r- B* r2 G5 c
; }! A# o8 j1 q: y- e4 z$ Q
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
) S' A/ p. u8 ~3 n$ @6 [1 e import json( _; |; }/ l- c- C9 R/ `
import requests1 C7 d; A Y( |6 n8 m7 K
( ? l8 y l @ J9 } url = https://cocl.us/sanfran_geojson) V+ g6 N. b" y8 w0 t0 V
san_geo = f{url}. \( a4 O- _% o2 V' t0 t
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)0 Z9 w- u* G8 ~
folium.GeoJson() J! h1 W! c& g) A
san_geo,
: ]3 k! @' }: x: R7 x1 M style_function=lambda feature: {
# f/ u9 I6 G+ m7 W+ { fillColor: #ffff00,' h5 ?: w0 K5 v( y; h( X+ V
color: black,
/ c6 [( m: Q$ |, s+ A weight: 2,
9 f b% q/ w( o$ R dashArray: 5, 5
* @, P4 I* W0 l2 d; U }
4 w; V5 t- G* ]* t& p C6 t: ?6 R ).add_to(san_map)5 `8 g& D- }6 L% e
. P" M# C2 ~* ]2 z" \
#display map& s% Q& ^" k0 }- v/ m6 ?3 D
san_map
7 G, t6 p; M' s" q1 q
/ j3 X" U9 Z) h$ P( c( F 8. 统计每个区域的犯罪事件数目
& k% W$ F" }! `8 j& L% S/ @
# Count crime numbers in each
neighborhood
5 {9 e8 I; y; O) m$ S disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
* t; R; b0 N5 n' R: J6 v disdata.reset_index(inplace=True)
# _3 A/ v% s( d disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
- v: S3 o+ x& a4 [
disdata
" F% V& h8 J1 M' F
* k& b& y/ B- `( h4 q- J- G" E8 S 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
% Y, W' j: b2 Z* |8 M6 P
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
% C) ]* q0 M% A8 \ folium.Choropleth(
( S7 U: D: B/ _ X) ` geo_data=san_geo,
1 R- [% W$ h1 s8 x data=disdata,
2 _( k# t5 Z- m) [
columns=[Neighborhood,Count],
/ m: B7 q+ Q8 g! v; n# Z
key_on=feature.properties.DISTRICT,
; k1 f' |; R e) ]9 k
#fill_color=red,
- C9 X- P& @, Z7 _
fill_color=YlOrRd,
# ^6 Z& i8 t. u! o" K; p fill_opacity=0.7,
4 ^+ x1 X0 I8 C4 v: J8 f line_opacity=0.2,
8 _5 ^8 I, v( G1 r% E. Q. G highlight=True,
7 x5 J' {! Q4 }* C5 g( X" T
legend_name=Crime Counts in San Francisco
: K3 N: t: w& J& c
).add_to(m)
A* a0 |# g; [2 g) U m
3 g. l4 m6 u; ?: I3 `# O& Y4 I
, r, t0 U0 O. J! c
( q) L) `4 q6 D: }3 q8 S: o* Z 10. 创建热力图
3 X! P" `4 l' q from folium.plugins import HeatMap: o9 @# }/ Z8 w) k
( ^( d8 u! ~, C0 G0 o( s7 j
# lets start again with a clean copy of the map of San Francisco
/ F+ J5 Y! K0 o san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
$ R8 }, |6 ]! ^9 n0 X1 E$ R {7 \* s
# Convert data format0 C6 ] Z) D" g9 V( f% K( b# Z
heatdata = data[[Y,X]].values.tolist()& R: O5 U( _0 j' g
" s3 T& [2 O' F* c # add incidents to map
8 t! U* C! o' ]& N: p6 k' _; a HeatMap(heatdata).add_to(san_map)
+ Q- g# B" G% E3 F7 x0 w2 b
* Q! u* e4 w5 E san_map
& `9 B) I8 n2 E2 B
" j" S0 ?0 u% O- O 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
' L# V, @ t- A- Z/ J 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
% k' t4 M* h* ]3 u) K' E; A
: t, L- b- v+ W, g! H
我的其他回答:
- E. f/ ~: G" H6 r6 e
8 n2 E& h, `& N
' S0 |8 i% m' s0 q" v& t
, {* q- s& x- T' b5 c! n2 |. l9 j 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
1 r/ I- `" X9 f" s! ]7 F ]0 F 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
! b+ @7 Q$ T$ [# y% y
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
3 o4 M" N7 b: x# p 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
' _6 d; s( Z% @+ u; m 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
P* \2 q) R5 K# S6 E