6 ~" n1 c5 y* C( D8 G
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
% e1 Y+ K9 @8 Z: d
7 \5 L B$ \0 U* `/ g) {- X. C+ o3 u
使用方法很简单,操作如下:
导入包,创建一副世界地图6 N- Y+ v; b, q' h# f3 c
import folium; |, i& o+ o% S# G
import pandas as pd# N6 m+ j- B2 M; z% }% f2 M
& _, A. _) T! ]* @% C8 H. F
# define the world map9 L/ E7 r2 T6 s( u4 K+ z* o
world_map = folium.Map(). E- V; ^5 @4 q- i8 p
6 G( x% |) I, w% M/ x # display world map
% n$ `8 X' t0 N8 O9 i/ h world_map
" \3 g* _ v! L# [ ?1 g
# \* L' K2 b7 B- i3 q! a 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
* Q2 A- M; O+ X/ s( I # San Francisco latitude and longitude values& _" p, D% [% `6 y
latitude = 37.77
: N1 h; r7 x P8 c* k- f/ _! r0 n longitude = -122.42
! K) ?/ Q3 G; N; J. m2 T$ B0 c C/ n9 L5 T |
# Create map and display it: P) l% g: T' i% c. X; E! n* H6 @
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)" t% K5 t! F" ~
# B. ?: m: Q/ M# ]4 b) F3 _ # Display the map of San Francisco( I$ v' Q' W1 n3 z; R
san_map
1 v; o5 x% s) r% M2 A
3 E9 q. t! F0 Y- p& R( m) p! D 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
0 i0 F6 b9 l4 H7 a # Create map and display it/ }( ?7 b- T/ c# m: s
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
0 c5 ^1 G* i8 Q! A& D) ^* F$ {- O
; P) f* X# ^2 t# u: Q 3. 读取数据集(旧金山犯罪数据集)
5 Q. j6 t0 |7 O# q4 w0 { # Read Dataset8 u& K/ B8 n, P% \# I* V
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)3 [4 R5 _: t2 j3 q
cdata.head()
2 @) S- h8 _, M/ }' D- C " y: G3 {5 i- G' \' F
4. 在地图上显示前200条犯罪数据
- e+ k# ]0 m ]5 c0 O& i4 J
# get the first 200 crimes in the cdata
: n" v k; k3 u+ E9 l+ J limit = 200
+ z" b+ L% ]6 o4 E5 M& C
data = cdata.
iloc[0:limit, :]
s% o$ G, w w5 w3 m+ Y. j6 K+ W" m, x6 u
# Instantiate a feature group for the incidents in the dataframe
7 `" P0 c+ x$ L6 A$ B, ^# @. Q
incidents = folium.map.FeatureGroup()
8 b! U7 n4 N- q" t, P6 h' K
! K6 C3 w$ [# R4 m# C2 m8 t # Loop through the 200 crimes and add each to the incidents feature group
" u1 G: D" U0 U8 M1 `8 @ for lat, lng, in zip(cdata.Y, data.X):
1 P2 g" Q" Y7 H4 v5 r$ Q; B. l+ H incidents.add_child(
6 ^" I( o5 |: E5 A% ~7 y folium.CircleMarker(
T/ N9 C" g" r7 c) C& y( E1 U4 N
[lat, lng],
# g9 \& e8 u# p radius=7, # define how big you want the circle markers to be
, J$ P2 e/ X. f7 ]
color=yellow,
: A/ O! ~" S' s8 l& E3 C! @" o! o fill=True,
/ V9 E/ V/ j7 X3 q) _1 W
fill_color=red,
; F% A/ w1 v( p fill_opacity=0.4
6 k6 j, K: D) r
)
% y. @1 d# F1 H )
; x5 k& e6 s+ d. B7 W
# i5 \( J* D1 |$ D8 R # Add incidents to map
. p9 b" N& i3 n4 g san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
9 |. D2 ^5 W, Z' Q3 w/ y, z
san_
map.add_child(incidents)
4 H6 v1 r9 ^8 C( T & `' ~0 Z, f+ m6 Q; ^7 |
5. 添加地理标签
& _+ t. V% {2 y Q6 ], g
# add pop-up text to each marker on the map
" Y% T6 K4 i- ^6 F5 Q
latitudes = list(data.Y)
% O5 w8 o, s8 C" t7 p- K
longitudes = list(data.X)
~# l: {1 k+ H% b4 t' p8 \ labels = list(data.Category)
7 S4 `, }4 E X0 r, h* w0 E% E7 V% b; v
for lat, lng, label in zip(latitudes, longitudes, labels):
; _; G( [: K0 @ folium.Marker([lat, lng], popup=label).add_to(
san_map)
! l% G7 N: }2 O6 M& _7 K4 r. C
% i2 S8 e# T5 j9 U/ s4 ?" `# N* a # add incidents to map
0 w( G. G- ~8 O. q san_map.add_child(incidents)
6 K" K# z% c; m8 i8 S1 x" c $ q, J$ h3 h. C( X5 d
6. 统计区域犯罪总数
1 |& v; D* A) N$ K% r* u% ^ from folium import plugins
7 b: S" {; g0 D. E1 f, n$ i/ r: u+ h! {( u
# lets start again with a clean copy of the map of San Francisco
9 u* S9 p2 v8 c, s- W& k
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
6 J1 n1 G7 p3 {6 t2 n8 p
H! G+ L) p4 q, |1 a: B # instantiate a mark cluster object for the incidents in the dataframe
) }" ?8 Z. N# z/ Y1 h incidents = plugins.MarkerCluster().add_to(san_map)
! u" ?& ~4 b7 o! E# k" O
- X6 j6 p: G4 X, J7 q # loop through the
dataframe and add each data point to the mark cluster
& v8 M4 R7 X' |0 k% f for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
' h$ S/ L! B0 I% u( _1 k
folium.Marker(
4 S" `5 b- H5 @) `* |% {. E0 I2 `
location=[lat, lng],
" a9 x( F4 I0 b6 X1 v I
icon=None,
1 }6 d/ J$ i3 F popup=label,
& K7 n& T: K: [8 _2 r E ).add_to(incidents)
9 S4 T, d, K+ K |7 v5 r4 ~, @1 j: M% H: Z2 Y. J5 i
# add incidents to map
* s6 j/ D" c! E6 ~8 ?
san_map.add_child(incidents)
3 y) l* y* b6 o) f, \ k ' C; b9 W; K+ J6 k, a' b- @7 `
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
4 S4 U: W* a8 p! B* N* r! N- j
import json1 ]. }8 a7 l5 f7 m& d
import requests$ @3 |9 g" H( C* Q
' @- ^, L7 p1 c* E9 ^8 \5 e$ M0 p url = https://cocl.us/sanfran_geojson" m$ X- O: W2 v' D7 i R
san_geo = f{url}; X% f' s2 z) f3 w! O
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
( X/ G4 g; X$ K# y& A. @ folium.GeoJson() M3 Z: S' l% S" u1 m" P
san_geo,$ B+ B: p/ ]* E
style_function=lambda feature: {
3 d7 U% C; O: |! t. I. v fillColor: #ffff00,$ o' ?: E- j# X2 D! h" D+ Z
color: black,, F+ y$ n6 `- U& E+ \( P+ i& k
weight: 2,* P: H' {' D; S0 b4 w+ J0 |1 K
dashArray: 5, 5
& q. Q: | D0 U) g( U( @0 g$ B }
4 d, z+ ?8 ~. p3 N1 [/ m! v7 [ ).add_to(san_map)2 u* R B- k J$ G0 V6 J8 P
) t, s3 u9 u' e" |( X: Z
#display map
! R+ B- o7 s4 a9 `. G: t san_map
, P6 K; z" j, l' H
" ~2 {0 {- t9 [5 `+ A 8. 统计每个区域的犯罪事件数目
t7 L' ~" b2 f( v9 G; p # Count crime numbers in each
neighborhood
Z' u+ x2 V% Q' Z% h6 k' c disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
D: g3 V5 o3 I8 T {* h- l
disdata.reset_index(inplace=True)
l5 G. @0 c' \
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
. M) @5 o; P9 Y! }1 J2 J disdata
0 j: \, ]% x, E' `3 e9 m7 M
4 Z$ T: J& \: o; I% B4 V% V 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
0 `2 F4 R- R k2 y+ `" m8 B' z) ` m = folium.Map(location=[37.77, -122.4], zoom_start=12)
3 o7 t( h, F, T. E
folium.Choropleth(
7 V3 N: X& u9 f- J geo_data=san_geo,
+ H9 H' F2 ?5 u9 w6 e data=disdata,
& S" U+ R$ I1 i- ` |
columns=[Neighborhood,Count],
* {+ g7 {( G) G3 p' H* m
key_on=feature.properties.DISTRICT,
! |$ W/ l% A6 v #fill_color=red,
" Y! D8 r2 W2 U fill_color=YlOrRd,
A% t' O4 P. W! F; f4 Q fill_opacity=0.7,
" `9 `* ^. S' I0 K, {5 v' T' U+ h line_opacity=0.2,
7 W" P) I% t& K highlight=True,
* D: \) j" I# ? legend_name=Crime Counts in San Francisco
# _- Q G' \- T0 _. D ).add_to(m)
) Q0 F: Z3 S* n4 V m
7 _: K0 K: g% z' ^ - a2 P0 g' D: I# q+ S: I
$ F, M/ \* _4 d3 M9 q5 x: G8 U( _0 y
10. 创建热力图
: ^$ G/ s# Q( N9 h3 x U
from folium.plugins import HeatMap
1 u' m; U1 n, o2 C+ z; ?7 I
, U" G1 L$ k6 ^: n+ X$ ^ # lets start again with a clean copy of the map of San Francisco
+ `' a* [# x) L" |6 r9 _* H san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
8 i) U& @1 Y+ O9 a9 \( x+ u; f
7 y1 {- Y) s( e; k$ u5 S # Convert data format
& Y, ~. k0 z9 j2 _) k6 S5 } heatdata = data[[Y,X]].values.tolist()
9 L- g. {! ?1 \. T. Y" W, {
2 p6 T/ e, C9 e6 B% s- n& G # add incidents to map8 s6 ?0 y1 b( f/ g" q+ n
HeatMap(heatdata).add_to(san_map)
6 ^- ?# g6 j- b* s' Y4 |( D: [- B$ `) V% R) a
san_map
6 m% K; D4 `7 O, z1 h
+ N+ {8 Q+ L5 H! G: q! k( r 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
. @$ O( Z! y1 z0 w# C. Z 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
/ o/ _* M; D5 W: _! Q6 R/ g, @0 q' _
2 H4 e' Z! X1 M: V k. U 我的其他回答:
: O' ?- \) D- B2 ^& @4 }
6 g1 ?' l( j9 {3 i$ q
l) v2 b) c& L3 N! p , u' j2 ]* S7 h3 U& o
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
# J! u6 } z; ~ p
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
( K% n2 g0 o/ ?6 g. M
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
( f- {7 D2 M) y4 A
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
9 H: P r' e9 G2 d& M) Y
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
" a1 T8 O Y* z. w