) o9 Y" K! y% N m+ e: I
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
+ L5 ^! [; ?' b
6 Q2 j5 |4 m) r: f0 a( R' g" z 使用方法很简单,操作如下:
导入包,创建一副世界地图
, ~7 M" v' V( h% d import folium" g" m& R& H4 Q9 `
import pandas as pd
6 [+ }* F8 N1 d% Y7 k9 k
3 ]8 y) ^5 L3 R9 o' B) @ # define the world map
9 `. l0 C4 i; d# _2 p world_map = folium.Map()
! F! R! y( S0 H1 C$ e& u9 G
+ v! U+ R, K3 g3 i, ^ # display world map
, _ g6 |0 J% I5 D- s world_map
7 }" U3 N5 i" H7 I) R
7 b# @! b: l( ?
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
7 _2 ?/ o! u: K" d( G
# San Francisco latitude and longitude values& L1 M/ s% ?5 v# I* [
latitude = 37.77
. F' {! Y% T: ?, G/ g0 T/ X longitude = -122.42& l5 @/ _8 R H# D- R8 ^
9 o. u& j* v* m" W# _6 y# J2 L
# Create map and display it3 G% w% Y- L, X0 D) N3 T! g
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
1 r# W3 q# d1 b; l2 D7 ]
/ \' \6 Z1 `0 C- \9 c+ { # Display the map of San Francisco
2 l9 `# f& R2 b$ R! m san_map
/ u/ m+ B% C& L4 Q3 @9 f# k
. Z: q- e% V2 g1 T0 N 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
4 R- y" y- `8 M$ L) G( Z J0 n # Create map and display it2 O- A/ y) u$ w$ g) f
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
0 Y( C; |. e$ ~/ ?$ D1 {% o9 L
9 ?+ w' w: u& V/ V4 u1 } 3. 读取数据集(旧金山犯罪数据集)
) S5 ?0 u; D" B, i1 K0 m' X
# Read Dataset! e6 @# [; L: o
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
' g% w/ Q% a; a5 d1 ` cdata.head()
8 F. ` |7 E' S5 ^9 V
; B; }: U2 x. M$ D' a' u
4. 在地图上显示前200条犯罪数据
/ D* F# S/ d% E/ q
# get the first 200 crimes in the cdata
) E8 F4 d+ ?5 \5 y( Z6 w/ ]2 b
limit = 200
^, l: E. }& F- S2 n; \ data = cdata.
iloc[0:limit, :]
* j4 H0 z- d( N; }; n2 q$ K% i* N; s
# Instantiate a feature group for the incidents in the dataframe
D5 L9 }4 j$ m: b& f
incidents = folium.map.FeatureGroup()
0 I. W! {) P+ h* g( n! r! i# L* K1 E+ a! r& c& |( |3 K& j
# Loop through the 200 crimes and add each to the incidents feature group
3 N% s( I' K0 X4 Q( e0 n$ n7 T$ E
for lat, lng, in zip(cdata.Y, data.X):
9 D: c! D1 P$ l0 j incidents.add_child(
- k9 s7 R1 s" u; a
folium.CircleMarker(
% t4 t0 S5 q. L4 K$ @
[lat, lng],
% T. C9 H" W( x/ u& s3 q
radius=7, # define how big you want the circle markers to be
& i3 ^5 a$ L) Y2 l/ {8 F
color=yellow,
/ U d1 ]8 S J" a' e e% N' ?% P; O fill=True,
1 s9 n0 |# h9 Z* m: Z
fill_color=red,
( R' o1 n; {( `9 C# i) o4 [* i
fill_opacity=0.4
* i% e+ y; u! v& q! a% M )
$ e i1 S2 q# r" `$ c& D6 D )
: u/ ?. w0 |3 c1 A0 f5 z
$ A2 c/ V3 y2 J$ T6 w) L% M C
# Add incidents to map
/ M; A2 F3 C0 d: Y4 [ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
' W- D- m0 ~2 J: u/ s$ g% Q* j; q
san_
map.add_child(incidents)
' y& ~% L+ U7 c) v& T: G/ u& u
6 v0 m2 [/ ~. l8 b7 z" y& a9 D, r 5. 添加地理标签
: A! a4 }4 z1 x7 U. z! }: n- O # add pop-up text to each marker on the map
" e2 r T% z3 A" K& P% S latitudes = list(data.Y)
& t# F/ E# r+ J& a- ?
longitudes = list(data.X)
7 E0 E1 j% d3 m: m$ r labels = list(data.Category)
% N. i9 q; ]# Q7 r* j. u! b# B5 ~
for lat, lng, label in zip(latitudes, longitudes, labels):
1 t$ E$ x5 M7 G8 q
folium.Marker([lat, lng], popup=label).add_to(
san_map)
( s6 q# u3 A) D* F" `2 z* T
# o2 y( e k: y" a
# add incidents to map
' b! r) N0 Z; F N7 X
san_map.add_child(incidents)
) e0 ]6 G ?- Z* S1 g! k1 `- j 9 g0 i8 v# C) t
6. 统计区域犯罪总数
' Y. I' h3 J% \( h6 L* b `; F5 g
from folium import plugins
+ |9 A) K6 Y3 n( x* ^5 @, `7 m6 b. v" W: \$ v! j
# lets start again with a clean copy of the map of San Francisco
# a$ d8 p% j+ k" @: M% W$ I# b
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
4 k/ ]9 Q# l/ }$ ^5 T+ m: W% N
3 Y+ l6 Q) E( m # instantiate a mark cluster object for the incidents in the dataframe
8 P% I4 n& m8 |$ B# F incidents = plugins.MarkerCluster().add_to(san_map)
q4 ^- p( g8 `7 m* e- c1 F' x
# l4 k; v5 ?, N' E7 k b # loop through the
dataframe and add each data point to the mark cluster
# V8 V, Q! ?+ N/ q
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
% D. Z3 q! M% M& M8 W6 m: f; E8 s
folium.Marker(
_+ q$ B9 t2 p' e/ c+ Q location=[lat, lng],
$ v# n$ d$ F2 c! \8 v4 Q+ e icon=None,
]0 G: K7 b# J7 g popup=label,
% O. r, ^+ E. e+ j8 X7 Q
).add_to(incidents)
7 y+ F' Q4 _8 y1 [6 F) N! U7 E" N( Y2 [
# add incidents to map
. y) {1 n) ~* w+ {" ~3 w+ j) B
san_map.add_child(incidents)
6 g5 g3 c* x( ]6 u
$ R/ F$ q' A) p0 T( o 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
9 k' G* y Y. {$ ^ import json
, ~6 P! d2 n* l/ T3 K; s import requests
* z4 _; p) ]6 c' S9 Q2 l* A% O2 w" n
url = https://cocl.us/sanfran_geojson7 z/ I- w+ {; c
san_geo = f{url}6 d( M& j3 y. y1 q+ @! A' d
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
: G* O4 c1 ]/ h7 r folium.GeoJson(
* U7 D7 J1 _/ b san_geo,6 N3 p+ t3 M- ], u
style_function=lambda feature: {
4 O) l6 k/ I$ @5 l2 x! F1 t fillColor: #ffff00,$ P$ X8 s+ b3 X; V. d1 O! m) o! D% C
color: black,
* L5 r/ X) j& O- J5 s weight: 2,
2 A8 z5 ?8 _) y dashArray: 5, 50 n3 N7 O) i% N3 @+ D0 {
}
0 C- ]* k( ~5 w! k ).add_to(san_map)9 \1 M% K) G$ [/ r6 d1 s$ V F3 s
+ |( _% z) f; u #display map/ g8 K: ?0 j4 K. v I
san_map
- k$ p h, I+ p) e- I, I+ l5 j( U2 w
3 y, t, p5 U* i5 T8 M9 q: G 8. 统计每个区域的犯罪事件数目
3 O' B& N# o* {3 @1 Z
# Count crime numbers in each
neighborhood
( Y# x- U( `( a, I# O; n5 o disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
, z0 G/ ~8 U6 |. Q
disdata.reset_index(inplace=True)
1 l4 I @4 T- A; m disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
W" p$ m; k) t1 h. |4 Z( ~, Z1 k disdata
" H4 S1 H2 W1 y, D; ?0 @/ @2 V3 ]) X & o. v& X- x1 d& ?* _" L
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
2 w/ O/ M1 T/ N8 ~
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
) a! Y4 z; n* U: x' H$ b9 ~) e% o folium.Choropleth(
) C$ v1 ?" c( j; O+ m$ r9 b% z geo_data=san_geo,
" B8 ]7 N/ ]4 G& M1 x1 H
data=disdata,
8 z; e- @* N' A* v9 s4 ~; n+ A
columns=[Neighborhood,Count],
1 d" n' Z' s/ v2 u; k key_on=feature.properties.DISTRICT,
! |+ i% ~. [# Q5 _& N d) g& M9 c
#fill_color=red,
8 W ^( ~. \5 Y- Q* s fill_color=YlOrRd,
2 ~2 y% `$ \' p1 [- ?9 j
fill_opacity=0.7,
# W; |; e1 E ~1 v, G line_opacity=0.2,
e$ W! Q/ F9 G' J( Z
highlight=True,
d# P! t! i$ y3 L$ m
legend_name=Crime Counts in San Francisco
! e8 T6 o5 ~7 H+ z$ K% D( H ).add_to(m)
5 D$ S Y$ K: i5 X4 A m
& \8 v5 C0 x! N& h, j" @- ~3 {$ k $ M: a" H* g. e- k- w- \; A y5 @
$ D5 V" L& `9 m/ m2 V
10. 创建热力图
x8 h* [; {- \
from folium.plugins import HeatMap( `+ _* E' i( X7 x7 u! \ n
$ v: ^. R/ P3 l+ C2 Y # lets start again with a clean copy of the map of San Francisco
" y$ R5 U# r8 _* ^ san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
! j2 N, K) `; L& u7 e4 u) K7 \5 @. @8 S X7 ~; Y
# Convert data format# i8 b) {0 Z& h/ j+ h' I
heatdata = data[[Y,X]].values.tolist()
4 {8 l" w: h2 P, U/ J
' y% t* Y0 u2 W6 z6 D6 n- s6 k8 @ # add incidents to map1 J' i6 b! o! R G) C
HeatMap(heatdata).add_to(san_map)
- J' G# {7 p" x, W0 e
+ J& T( `: @2 b9 i/ j# g1 ^% P san_map
- n7 g Z: G4 k
8 i" {# _ v. R0 l- _; t
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
- Y2 t4 S% P" O! b5 ?; v' P
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
6 Z" J- }' B7 \6 x4 N* B
, z. C7 i# E) a, W9 q 我的其他回答:
( d7 j" a! K9 V4 E o# E' l
; Q- g _! n9 ?% i
" G) A6 p4 M! e3 p ; E5 m: R! v, L$ K( \/ B
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
! ?- C( J; x* K6 |0 C: Z 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
L5 T3 }) _3 l2 X* z6 o( N4 O3 ` 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
; F1 \; M6 e: D& W7 d, I$ |, I) k8 t 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
" E0 r0 l" S# D9 j+ k( S0 i
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
4 W% Q" e& s7 T