# |" C, T# w2 g6 P$ B$ n# ?5 B 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
: H4 j# s3 w9 R7 l- p
0 k) ?5 c* e7 l6 @
使用方法很简单,操作如下:
导入包,创建一副世界地图" `# p7 R7 t6 }2 ~4 A
import folium% f C1 U5 m4 L& x; r3 Z
import pandas as pd
7 K" v5 L9 H- c ^6 G- p6 ?) ~0 E* U' B( _7 z
# define the world map
" ^- t7 B+ b3 ?" }& g/ t- d world_map = folium.Map()6 R5 f t; s! ^: e% ~2 y
, Q/ T0 p% t! T, T$ _+ w8 D# r
# display world map" R# J3 t+ i; R+ J. r5 b8 j- [
world_map
+ r/ a( y8 q. Y
8 D1 w# L. i4 n# G, k0 }' d8 ^
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
: T3 `9 P* x/ Y: Y/ i+ y # San Francisco latitude and longitude values- A- z* w# o6 N3 S; s2 G
latitude = 37.77
" V; h( a2 ~& q5 m' a0 m6 J" D1 M longitude = -122.42
- v( F4 [- g8 b/ a
! m$ e2 v# Z& T" r/ {; |6 Z # Create map and display it
' s, s. d; @2 i, A san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
& U7 l% o" l9 H0 [3 d4 M- F9 _* I) C7 I" M" d. l
# Display the map of San Francisco4 \1 s0 P T3 h! h M9 B7 H
san_map
0 y" ~8 h7 \7 M
# Q/ x. E4 g. a2 P% a1 _& k+ z 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
; _ q5 U2 Z( B& C& `: ? # Create map and display it
. E" r; W+ { K7 F& u san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
. o# S; v( T% J x8 v4 K& e6 }1 { 8 M) i7 x! T3 X( B$ [" S4 i
3. 读取数据集(旧金山犯罪数据集)
0 T8 Z, g' U1 j8 h- d+ J0 @
# Read Dataset8 b& e) ]3 [5 [* B
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)% C& p# c9 E( {$ I2 K: K
cdata.head()
# N( _$ C3 B! h6 ~( `8 Q. [7 a5 z
4 K/ O0 K) H# {9 ^ 4. 在地图上显示前200条犯罪数据
1 i" A! T/ }" p" z+ e/ K5 N
# get the first 200 crimes in the cdata
8 {$ O# P' O7 w# C/ O% N limit = 200
2 m$ S$ k' {( Z s& ~# r
data = cdata.
iloc[0:limit, :]
& K' f/ P8 l& s5 @6 E/ D2 d9 s5 p1 J* L
# Instantiate a feature group for the incidents in the dataframe
# ^/ `. x5 d1 ]* ]: _' G. _
incidents = folium.map.FeatureGroup()
; j( ]* Y) ?) i2 r4 \& K [2 q; `
- R+ f* \2 O8 ^0 K: F! W
# Loop through the 200 crimes and add each to the incidents feature group
" l4 X! J4 F9 @8 C" v for lat, lng, in zip(cdata.Y, data.X):
9 ^! {/ `; w6 D, m incidents.add_child(
4 d" A& H5 R$ |3 T- q folium.CircleMarker(
% A- m7 B/ U: ~- t
[lat, lng],
2 D/ P# U0 c( w9 l9 Q) N+ c- C$ @
radius=7, # define how big you want the circle markers to be
5 p, [4 q! d6 N% m- q color=yellow,
, L. _: j p& S+ R2 }+ S
fill=True,
5 L4 Q8 @ T' n$ X. G4 T3 ] fill_color=red,
5 @& C: ]; Q! }/ w& ?
fill_opacity=0.4
/ S/ m5 o' k6 ^' I
)
' ?. R/ i, b: _3 c: z+ J
)
" s: g6 M o6 I7 I3 i
8 v+ [% z- h/ z/ S # Add incidents to map
& F4 W% Y, q$ X san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
* [7 y$ X. v9 Z; e san_
map.add_child(incidents)
1 E9 g2 l# _, H6 K" e- n& [
6 g/ Z6 v# ]+ x; q* P
5. 添加地理标签
! M5 T; z c1 m/ [- \% q # add pop-up text to each marker on the map
0 _6 h P( `: E H' y& Y
latitudes = list(data.Y)
: `) k' B* R( R; { longitudes = list(data.X)
9 `$ U0 D: `. |: l% y3 R labels = list(data.Category)
3 U9 t+ P$ |3 G: M1 A9 t$ N2 E2 n8 J; b! Q# G U$ |# \6 R# k
for lat, lng, label in zip(latitudes, longitudes, labels):
) B. c) ] N' C, t w! Y folium.Marker([lat, lng], popup=label).add_to(
san_map)
, l8 p$ P) ~5 ] _) q% j. V$ ]' H# p3 z" b/ w4 o
# add incidents to map
2 K* D, C+ i. g! q% } san_map.add_child(incidents)
+ z8 P$ i5 p d; I% U5 q8 }
% }6 }: `6 ?3 P3 f3 s. m 6. 统计区域犯罪总数
# ] B6 U: Q: C! @5 s- z
from folium import plugins
! E. }( U+ P7 e
, I0 A* T9 @* x2 V1 Y # lets start again with a clean copy of the map of San Francisco
% R2 \3 V! J: L6 [9 n% K% q' M
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
# _$ t5 }6 K9 _* \ }7 H! p# z
" J% V# Z% r0 K+ w2 e, t
# instantiate a mark cluster object for the incidents in the dataframe
1 W6 R {8 o5 e( y. r6 [/ {7 ? incidents = plugins.MarkerCluster().add_to(san_map)
7 T9 T5 `1 u& o
7 R0 e4 J) c; J( ^1 R # loop through the
dataframe and add each data point to the mark cluster
$ C) T z+ ?$ f# O) C0 Z for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
: y- n! ^# J3 L9 a! y5 J5 k1 R Z folium.Marker(
( ]( K% T) Y. u location=[lat, lng],
9 w$ \" Y9 Y. c- \
icon=None,
6 W; G6 W5 `6 v; B% L% N1 U popup=label,
8 B+ s7 l& C! X# c1 s3 \# j ).add_to(incidents)
, w0 F, n# r: p) ]! L; P
4 Y" b+ ?6 b& C- x* Y$ @6 W6 v
# add incidents to map
3 Y' p4 ~0 i' k; K; E/ @* o san_map.add_child(incidents)
1 T6 P$ c6 ^" f& t% ]* d
4 s) m0 q$ h5 ], ]5 k
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
5 m: t2 u0 Q$ |" u5 m, j
import json
, l# [! d) Q! B import requests
2 W0 i/ ^& E) ]; e' ~, O7 ~) Z- w2 l6 ?
# z: |/ j- Y( F, n# h% n! ^ url = https://cocl.us/sanfran_geojson: Z& L( f7 O! L0 ~6 M$ \
san_geo = f{url}
- r( X1 \5 _0 l san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
* j' T- n, R. s! k5 _! ]3 b( g& N5 e folium.GeoJson( H. @5 B' E% k0 m$ v# t; [0 ?
san_geo,
. H: X8 X7 A- p* {+ G+ t style_function=lambda feature: {' w# \: G5 O' |- s
fillColor: #ffff00,
( Q" J0 N8 _- n. o/ M( d! N- U color: black,
* k3 k9 ~) F, |& a weight: 2,8 X; F1 G+ f6 h2 @; M) L
dashArray: 5, 5% y8 _% ?" r7 _/ n
}
y5 p( Q' h$ f ).add_to(san_map)
. J& n! X- S) X, E: M" a
; ?3 H' t( C/ T9 ] #display map9 @+ f& B. _" [& f
san_map
2 Z* Y% r7 h2 M6 b, j' l; E
& e9 J! f7 l5 |# t; s- h- v 8. 统计每个区域的犯罪事件数目
2 [+ c% Y2 a0 T' N* U5 \ # Count crime numbers in each
neighborhood9 m3 [5 H6 j4 a0 }8 R* I1 _
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
4 G9 c) h/ t* E7 F2 T disdata.reset_index(inplace=True)
" E; y0 ?) \7 y. n6 S. E; Z
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
, G1 y4 v5 \5 |) d* ?; i disdata
! |+ W. S3 b7 q% P+ V3 S/ u- T
/ t% n! Y3 M. S$ f
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
/ X3 e5 b- z1 o; B
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
B0 ~& N x4 r4 b9 L- N" } folium.Choropleth(
1 u8 H, \$ S7 E( b- Y
geo_data=san_geo,
+ i j, n/ v3 o# H& A
data=disdata,
/ o$ R, Z- G9 j3 F columns=[Neighborhood,Count],
! J. T# j2 Q; c" [5 _% J' | key_on=feature.properties.DISTRICT,
& \. {5 |1 E% T) z. {2 ^ #fill_color=red,
, n& F3 O; U8 V fill_color=YlOrRd,
1 z5 Y# [: K" K
fill_opacity=0.7,
/ H# J2 U5 ^- m3 i: a5 }' E% H: d+ r line_opacity=0.2,
7 y9 S6 Z8 h8 t# v highlight=True,
3 C6 |4 @: l5 `1 @8 T4 D a% C legend_name=Crime Counts in San Francisco
" A9 ]* C, {( F5 h ).add_to(m)
, y9 Y* v ?3 w( o1 i8 i# B m
, ~; E! i5 k7 I8 G# D4 l
! M+ p( a& ^7 K * m u/ P( j. F3 e# P/ N
10. 创建热力图
% R1 @/ z, n- z$ ?, n8 h- w. I3 D
from folium.plugins import HeatMap
! |% z' d( ] |$ S; Z4 M/ \9 r. k7 j. m
# lets start again with a clean copy of the map of San Francisco& A* @: d! U2 e/ o" Y2 N
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
& N/ O8 y6 D+ S; T! ?
4 p5 f& n0 y/ {( I9 E! H2 }8 _ # Convert data format
+ u6 D$ n, q2 F7 i$ P! j heatdata = data[[Y,X]].values.tolist()
' h! |* P7 _) }+ \( h2 l
: l) f5 X& S# e9 B # add incidents to map* D+ |8 v" {. G8 Z) W
HeatMap(heatdata).add_to(san_map)
5 Z, A; }6 b3 w9 x2 ]. k" ?- V. T/ B3 ?- G
san_map
- Q0 u6 t0 U8 C H
5 m& b, \+ z9 U. o+ x+ s
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
, b8 Z- P5 v9 S( C( i5 B: Z 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
/ m# Z0 e0 [' P! c6 \# v N
2 Q, M" ?; w2 I; x: x7 e2 X 我的其他回答:
7 X+ p* `+ U. K0 o4 U9 D$ O9 Y" s
8 `; B0 H5 j6 M* t+ m" z
, X& h6 l7 S& `% M$ L ~
2 m4 U$ B7 I& T# M# ?/ j3 U5 u 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
6 L5 z% \0 F( t! B* c& k0 \ 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
) @( r9 X5 t5 Q/ R5 W' m
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
7 y7 p. }4 i; s- P1 s
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
; @* u' C; Z" E! S) z0 S( A 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
1 a: g" r4 U; x% R9 A9 |