! S9 }; H: }# u' I/ Q
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
, C5 i$ k7 I! B [- }( |: {& W/ d+ P * W: V9 D, h V- [1 i
使用方法很简单,操作如下:
导入包,创建一副世界地图
- n5 C; w9 z" x) R" d/ u2 Y1 L import folium
$ l- l- {) M" {# b import pandas as pd6 ^% p! s# Z! S7 J& o. x) Y
3 \- ]9 o/ f2 j2 q0 T' F
# define the world map
' F5 B2 e* K/ w world_map = folium.Map()
9 I2 f& F7 H3 V% p) k- w; j. a" P3 F! w4 b$ d( I1 o
# display world map* s& y5 n* a# O3 |' Z0 J0 p
world_map
& j. V$ h. o1 V: @+ t
8 H$ M. H$ ?. p 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
% w" D: ]- K" |, m) r( D& F8 \8 H
# San Francisco latitude and longitude values
* |" E( R B! T4 J } latitude = 37.775 K/ @2 T: W7 ?, u
longitude = -122.42
n9 h: m. w6 A; {+ m9 j& w7 [' }+ v P
# Create map and display it3 s/ J& B1 h% \
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)0 E$ T# v w; g- K
1 _. i" N. e/ N; [% v
# Display the map of San Francisco
! N5 y7 e8 B W) A+ M6 j! X san_map
/ u- }' b6 f. T2 R5 _1 w 6 ]9 @ H Z! E: G z5 y: w0 T B
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
# {! g) I7 |4 g6 D# I* I& a/ i- K
# Create map and display it
+ O) {7 M5 y- n. W$ a7 S' @ san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
3 M% p. l6 b% j' C; j& ^/ a2 b
N3 h. T* a% z5 P
3. 读取数据集(旧金山犯罪数据集)
8 w! [! V1 ~! q+ S- w( V+ r # Read Dataset
6 ^- _# ?6 Z3 G$ E8 A/ \ cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset): a0 `) k v8 H% u
cdata.head()
0 M) h$ d! `0 D% i$ n
9 C% _& L$ F( ?- |( \ 4. 在地图上显示前200条犯罪数据
' y7 j3 W3 ^ T9 ~& E4 `
# get the first 200 crimes in the cdata
3 m1 E+ Y6 V& |' t) J. g
limit = 200
2 S' V9 S" S9 @
data = cdata.
iloc[0:limit, :]
9 f" f% }. \7 _* V6 ]5 _. a! w, b( B
# Instantiate a feature group for the incidents in the dataframe
" e7 {' r: ]: N incidents = folium.map.FeatureGroup()
- H& r; b3 X9 d, s1 U$ `. B5 V
' x( c& d; @9 y/ f2 g/ Z # Loop through the 200 crimes and add each to the incidents feature group
/ H+ i- T* e' i for lat, lng, in zip(cdata.Y, data.X):
$ q* a( k8 A$ y! S) A incidents.add_child(
& k1 ]; O- w z+ e
folium.CircleMarker(
: t2 d, b( `* e3 p+ w
[lat, lng],
& N3 |: i; H/ b' V; n
radius=7, # define how big you want the circle markers to be
% [" {5 p2 w( k
color=yellow,
' O6 l9 D& a0 R/ h3 u- |* o fill=True,
; ]3 r0 d' L9 }9 W' X fill_color=red,
& h F8 H( ~/ g
fill_opacity=0.4
6 O: ?$ @% p8 B! E; ^# v+ f
)
& `: l4 f5 B5 [0 {2 }3 R- M )
3 ] f. m- L- k
2 \' M5 L1 P' T" G* d # Add incidents to map
0 |3 g5 S7 f+ `( v1 U% F/ ?0 \
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
. O8 W( j U, J/ n s& V, d san_
map.add_child(incidents)
H2 s3 O7 b0 `* v; o
; o! J1 y: e# x5 y. v 5. 添加地理标签
4 e- g; A0 R) x4 T7 q
# add pop-up text to each marker on the map
$ M% q( w3 B+ n6 t1 @ latitudes = list(data.Y)
5 F9 ]0 V: D7 Q1 L2 R4 A' I% e: o longitudes = list(data.X)
& ~& e; {) ], v/ `5 P; x4 A# @3 Y
labels = list(data.Category)
# H7 r' o( G! t1 q( t1 h1 i' f" _, } a! F2 ?6 v6 N) Z
for lat, lng, label in zip(latitudes, longitudes, labels):
3 t9 t/ s! O k1 J8 f p folium.Marker([lat, lng], popup=label).add_to(
san_map)
8 r4 M# N+ V* o6 ?. t, i" v' E0 b- } C5 T$ y. f+ e ~( D
# add incidents to map
9 X5 v$ v+ W4 C$ w6 G' U8 U san_map.add_child(incidents)
* [2 Y( v- N ?
; o$ \% |. U0 u! j: i& W3 |; ? 6. 统计区域犯罪总数
9 F) H* s4 k' P% c" g' s! N from folium import plugins
: ?# h [0 ^3 S; N- U% u. J+ O9 f9 ^$ w- l# I- `0 {7 \
# lets start again with a clean copy of the map of San Francisco
9 i1 Q, W7 N$ D) L: Q: ^
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
; y* |3 x. x+ h" U0 j
' Y c% ^9 z0 a) K7 |+ i7 F
# instantiate a mark cluster object for the incidents in the dataframe
% h2 `3 @% E' f) z
incidents = plugins.MarkerCluster().add_to(san_map)
[3 v3 P4 W& T+ ^
W# {8 t) p6 A: D, _( @ # loop through the
dataframe and add each data point to the mark cluster
0 W& U+ s( O& E; `- T5 {$ k5 E
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
# Z. C1 |. y4 N y+ n5 m6 E folium.Marker(
# ]& j; J( a! |: p location=[lat, lng],
( S2 t, n! r$ Q k
icon=None,
% x" b# o/ i- j2 {! h8 {1 R
popup=label,
5 r& Y* V+ g6 L( Z: g. o ).add_to(incidents)
8 n, i- k: s# o2 [6 r2 G
& z7 D, `% K; A0 O' j5 p # add incidents to map
2 i; d; a, I+ O& A& s# W# | san_map.add_child(incidents)
# m1 F7 h- h: t$ S: S. {, i
u c/ y, o+ C7 ^, Y( z
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
: P2 @: n0 A* p; P8 Y' K# j$ N import json
; g3 ^& O, X8 m import requests
* l. O X9 }6 l6 e5 D: c4 e2 L+ r) I3 f% W* h- z
url = https://cocl.us/sanfran_geojson! d9 P5 J3 w8 {8 S4 |7 G& @3 ]* X
san_geo = f{url}
6 }$ _: V! v, L' B4 ?! l' V$ ~ san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
) V. X. F5 p9 p" ]+ [ folium.GeoJson(
$ a; T* e' P5 X; y2 ]: A san_geo,2 I; u$ ^$ [& Y T
style_function=lambda feature: {
( W. U0 f4 b& c/ t1 W fillColor: #ffff00,
5 K& U# s8 y4 d z# o+ D8 e color: black,
- \% J7 v/ q+ Y) q. k1 A( f1 G weight: 2,
- m8 A; Y+ f% T+ f dashArray: 5, 5
# t1 l. b- m5 Q1 u: t2 n }
! P# L) h6 H9 \9 B/ |" x5 w, T ).add_to(san_map)
5 F$ x) ~+ U$ r9 d' b7 g+ W* L0 A! m8 r
8 ]- b% U% A0 j: M9 s0 }7 R #display map
P( b/ F" E4 D0 T san_map
, `% L% h6 T+ A/ m% t0 }6 z$ M. i! S & C/ b/ V: ], W F, l ]
8. 统计每个区域的犯罪事件数目
' m5 D2 O! \. Y3 o+ m5 S # Count crime numbers in each
neighborhood4 h3 E8 t0 z2 y) D
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
d' m1 `7 ^" L/ ~: T, t
disdata.reset_index(inplace=True)
- E" T+ G2 i7 b* B disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
7 H+ S8 E. `- E" u0 R
disdata
3 B6 u+ b2 ~) j2 W' B# d+ F) w 5 x) A+ g6 \: k3 F& x& m. f0 g
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
9 q! _0 H& A1 i( |4 T7 o& N" |) _; n
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
% n) D# P5 \0 v/ r1 M3 N2 K folium.Choropleth(
+ K) N8 G* x% d) e
geo_data=san_geo,
. m% s$ J5 z4 v% C data=disdata,
. r! B: u; Q" T" @) E ?
columns=[Neighborhood,Count],
* s, |/ R2 @2 t4 E% M key_on=feature.properties.DISTRICT,
2 {. N+ }; ^7 I: G( | #fill_color=red,
5 `1 K: K/ X( v& O. p8 \ fill_color=YlOrRd,
% R6 U0 T/ j0 t/ b' j* V9 c fill_opacity=0.7,
! V0 _. z/ s# n6 f/ c7 K. D
line_opacity=0.2,
- y- W9 k( z+ ]9 Q& N. Q
highlight=True,
6 p. h4 @ U A# w+ A( v% K+ I legend_name=Crime Counts in San Francisco
- J( q: Y1 i* H$ l
).add_to(m)
4 A a- G3 g9 b7 |+ N, M
m
) Y& v$ I- B4 _, p2 @
; K; ^% L* v) Q9 t! N
+ M# m. v D3 g- P& c
10. 创建热力图
+ T2 ~2 v, d* J+ ?! Z5 o) z
from folium.plugins import HeatMap1 E( ?+ C4 W! ?6 j+ ?- G0 }
" R" W2 X) I9 q* R
# lets start again with a clean copy of the map of San Francisco4 [$ \# q* I' _" k
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)' `6 N5 u: p4 V
. y( g( P$ w: B8 d # Convert data format- `1 F$ Z# Q* p* y
heatdata = data[[Y,X]].values.tolist()
4 W+ q( G* ]8 U2 |7 X# L0 E" g
5 B$ a3 s% v5 g2 a* g # add incidents to map
3 S0 u" J# i* A y: X6 Z HeatMap(heatdata).add_to(san_map)0 F+ K. Z2 h: w, ]( l: R' [ O; E
: u1 T, }+ I; k: p2 o1 p
san_map
" v5 R2 o; F0 r9 a' F 3 e5 n4 z; Q/ h8 u
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
6 V" K/ K0 K$ z% S; s
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
" i; a( z* f* O/ t
9 A+ b/ }; Y. a- {8 g, j, H
我的其他回答:
& ?' c3 Z! @! s' I, I- v ! C: x. H( Q2 G( w
. Z+ p5 M/ o1 S: u# Q0 }; a% N ( [; ?2 o. \' |% }1 U' R
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
) D6 H) ~; U `% g$ ^7 D. @ 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
4 @$ R+ I; G7 t* H1 X 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
1 w3 h, j. T& W( ?: r
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
0 |$ n0 Z y- {. v" G2 f3 F 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
' w0 S: d4 t: M, P3 L) _