+ O5 W6 }% _3 Q) v! {6 Z
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
) b& |8 X* F% L" }) N8 j3 e5 H
5 v& s3 R1 V; S9 X( C, K& x' O
使用方法很简单,操作如下:
导入包,创建一副世界地图& M6 K. N; |5 F! c! u! N8 |
import folium* o* f6 F: W- m" h+ K
import pandas as pd- b" k7 t" A' s
) P5 R! m; y* s- M0 l5 H
# define the world map
/ s, e; _: t) [) S+ y$ J world_map = folium.Map()
4 D4 D" A9 e# m0 i$ N2 e! N7 l
, \/ E/ p4 D8 ?, ^: K+ g # display world map- ?! K) T! n* i, V
world_map
; s2 L" l/ R) n2 }/ x 3 p6 k6 _4 E5 q+ W3 x
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
3 L% }$ Q/ m+ N" S% @/ c& {
# San Francisco latitude and longitude values9 K7 S; m2 \) w
latitude = 37.77
- U0 |5 Y% I3 I; h" ? longitude = -122.42
, {# t: \" S* @1 {, ?8 Y3 r& `/ B8 Y8 i; H# p" w+ P H# q
# Create map and display it
% g4 U1 R- l! `, |4 j) {* [ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)1 k# T7 A- N4 S& g* ^ e5 g
% Z% d; \5 M" l# T # Display the map of San Francisco
$ Z8 `/ R2 {7 h+ M san_map
1 U6 ?0 r$ F: l* z 5 N5 R' F0 T2 S6 f, @4 m
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
9 T. V) u' I3 |' j) s/ d
# Create map and display it- }: g& V2 ^6 F) F$ g8 a$ \
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
4 H; }# g) m+ M' L2 v( Q5 X1 E
5 z9 F+ n+ h, N4 p 3. 读取数据集(旧金山犯罪数据集)
# J. o9 b! f8 t. A; p
# Read Dataset) q5 w# @8 ?1 H, w& y& D0 X
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
0 x T$ T: d: O5 o( z cdata.head()
& h6 H+ i3 v7 R" J$ o
% f0 _( H/ t; o, y& Z 4. 在地图上显示前200条犯罪数据
2 ~, ]1 `3 D2 R% K! A
# get the first 200 crimes in the cdata
! V( l+ j; y3 q! Z
limit = 200
* V/ t5 T4 E4 L0 b, c data = cdata.
iloc[0:limit, :]
" K( K8 x( A( n- O" \
Q8 I9 R4 Z5 t # Instantiate a feature group for the incidents in the dataframe
( `' n" L8 O$ b5 i' @
incidents = folium.map.FeatureGroup()
: e1 b8 P/ e* D9 F9 Q9 }
$ I5 T! U/ C8 s1 V+ `
# Loop through the 200 crimes and add each to the incidents feature group
5 i/ i5 c3 S; v! F! ^ for lat, lng, in zip(cdata.Y, data.X):
1 x/ I. f8 }% ^1 r _7 h \- _9 z
incidents.add_child(
7 o' d( m. W; l* k' o4 G
folium.CircleMarker(
3 X9 v3 \7 Y D( t Y9 U* a6 q
[lat, lng],
0 S7 {$ Y) {0 L7 _6 o! G- L) s
radius=7, # define how big you want the circle markers to be
3 D9 ^! J/ S8 o% y: O: V6 c
color=yellow,
; X7 h" m3 x' v; k
fill=True,
% e- T/ ~3 w6 U$ t2 `) l; k; o fill_color=red,
5 K1 W, x. Z5 n3 \1 y. g1 W0 m fill_opacity=0.4
- {& x2 p9 p) u9 J1 m% S4 _
)
2 J+ N4 c& V% V7 q& m) P& y0 v )
7 j4 x' x8 Q0 [, b9 V) n
% _* g! J9 [9 i8 ]$ X+ q' |
# Add incidents to map
+ V" ^1 f7 \, f8 m* L0 M san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
$ s) W! I+ S4 B, x4 q1 ] san_
map.add_child(incidents)
- P0 Z$ M$ T* |& j( u
8 d; I6 A2 b4 }0 Z! @7 f+ ^ 5. 添加地理标签
7 x' e4 Z, N. y0 _8 O9 g
# add pop-up text to each marker on the map
* {, ?" O+ S2 _. F, I/ ]! F0 h latitudes = list(data.Y)
3 m7 s9 G! P, {. a: n
longitudes = list(data.X)
# _. A3 `, U, X* } labels = list(data.Category)
; w# J+ U! h/ `3 z# l& p, s) K
4 {9 D3 \2 I2 Z for lat, lng, label in zip(latitudes, longitudes, labels):
7 @2 d; G1 h: `5 U6 p, l
folium.Marker([lat, lng], popup=label).add_to(
san_map)
6 w3 M+ _0 G- l+ n& e
) u# C3 X g1 @& S% U3 ~ # add incidents to map
3 W2 |, I$ H( b' O% s/ ]
san_map.add_child(incidents)
/ R4 v/ Q" q; f I5 S
' }; T( a, D7 C$ \5 O3 t4 J& c, z
6. 统计区域犯罪总数
9 I6 m7 ?1 i& G: l
from folium import plugins
. l2 u3 Q0 e) h; j1 W
3 X3 |/ f6 w9 w) E' y7 V/ U # lets start again with a clean copy of the map of San Francisco
9 s: }: C$ d4 t san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
, ~; W1 l. M8 Q7 Y+ N! h: M; i1 o: f7 l' I0 n4 S
# instantiate a mark cluster object for the incidents in the dataframe
% N( M o' F1 }3 `* p7 e
incidents = plugins.MarkerCluster().add_to(san_map)
1 l+ `' N. _3 k* E9 W3 N
) U% P" R9 v& j5 V # loop through the
dataframe and add each data point to the mark cluster
( g7 F& M: U* O7 u) D3 j# o# H- ?9 {
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
* c4 g/ b" I3 B, y4 u/ v7 z; B
folium.Marker(
* S+ ?. V6 z/ W* k% m
location=[lat, lng],
! F! I5 G3 S; b1 A/ s
icon=None,
3 o" |/ ]1 S1 s% T9 B* s
popup=label,
- h* |5 c" w3 m! r
).add_to(incidents)
4 @/ [. F( Z- y \" w
; a8 C2 o4 Q4 d # add incidents to map
1 C$ q }, f' Y" u san_map.add_child(incidents)
- q0 b) U# x! r( U
6 O: R) R$ z, ~2 ^% K1 |
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
, V" b p$ [. p$ S/ `+ P import json
# X+ R9 F# R& p5 c& x6 C* {2 y import requests6 b3 K9 d, n. [/ W
& W U) ^. _7 S) A! n) v: a9 v url = https://cocl.us/sanfran_geojson1 y% J- I: P$ |% F8 B
san_geo = f{url}. ?5 I* z" T* P( R9 [% ^! a% F# `
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)9 G( Y8 I+ K3 T I# X
folium.GeoJson(7 [! {3 S' `6 o6 v6 N3 u7 L! b
san_geo,
: O' w7 Y% d; t/ [( w8 g style_function=lambda feature: {
5 t2 E9 Q v) D" i! b8 A& \ fillColor: #ffff00,
' Q- A4 R- z1 h/ a" J( V5 e& ?5 R color: black,
; d) i/ M) L3 Q weight: 2,' Z" T9 r4 A' Y! X; _
dashArray: 5, 50 C8 M! Z9 E/ g& F$ Q w' Y, I
}
( w" D; a5 S0 c, r$ b8 @ ).add_to(san_map)
/ a Q" U3 V: ]2 S$ D2 S! D2 ]: M( Y
#display map
1 o, c& q/ H- d# Z' ^1 `+ A9 p8 g san_map
* C2 ]: Z8 `7 t7 O" e! U
* K1 q1 Z" f# X' F 8. 统计每个区域的犯罪事件数目
9 f# r) K6 v: V2 l0 L T' F # Count crime numbers in each
neighborhood
( U8 h( O5 S- H* }# I/ \ disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
1 e5 i$ j j% F6 W4 c disdata.reset_index(inplace=True)
! u, s( @" k$ A4 `
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
% P( d/ ^) A/ H. n7 `; o* Y* Q. R
disdata
, f5 Q: ]: s. s3 [; ^4 i
! q- P4 g2 @& u% L4 | 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
% y6 X: W6 I2 j2 }3 }6 s m = folium.Map(location=[37.77, -122.4], zoom_start=12)
) x; ~/ @& H8 ?1 K$ c! e% Y5 t folium.Choropleth(
V( ]5 C" ^ e# [6 e) q4 o* o$ f
geo_data=san_geo,
) t0 E' @. w- ?6 v: ^
data=disdata,
! `/ D9 V, p. z! m columns=[Neighborhood,Count],
9 K8 _$ n6 r0 I3 S key_on=feature.properties.DISTRICT,
) K% Q/ b% U" Z& o) b; u #fill_color=red,
) s" R2 o E# ]
fill_color=YlOrRd,
3 X3 A: P e0 a: z fill_opacity=0.7,
- t5 l9 s3 d8 ~ J2 k& I
line_opacity=0.2,
! d- o' d( S2 a e/ n highlight=True,
$ N; b/ i& u$ H! q: M: p: k* _1 E legend_name=Crime Counts in San Francisco
3 B f2 u/ \4 y; d1 c
).add_to(m)
3 j {* W' _" |+ Z3 m
m
) E) O/ B3 \1 S- T; V1 C' S7 l5 p
+ [3 F$ z: G& ^ x' `" f# X
) g; J2 w- A9 s! @& O b V' v
10. 创建热力图
6 k v5 J9 D' n1 x. s8 C5 c4 E
from folium.plugins import HeatMap6 p! d% N- `8 q7 b
5 D% L. }( E0 [+ l0 g' T' C
# lets start again with a clean copy of the map of San Francisco
& ?; o6 K! o& n. F# E san_map = folium.Map(location = [latitude, longitude], zoom_start = 12). N+ [7 N. R( u0 C6 y! Z
$ _4 J A5 m# M' p/ U# K # Convert data format
4 e' e: \. k: b- m, F- ~/ J0 [+ g: f heatdata = data[[Y,X]].values.tolist(): w9 [8 ~7 T+ {4 |( C' Z6 ^
; Q3 B' Z1 n t3 m
# add incidents to map
& m( O9 @" o5 _1 ]! u# C HeatMap(heatdata).add_to(san_map)
3 ?% C8 z8 T/ U! e" |( W2 L& ]
2 M; j+ H) x" C) r* K san_map
5 d& T: N& z8 @' W
1 H* `/ t2 z. g
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
7 q8 ]/ Q4 {$ ] O2 R. D: A 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
6 d5 U! a$ R* W) |5 ]
/ w; x4 X9 J* w& Z% _ 我的其他回答:
. t) V; J' u# j3 J( r
5 |! Z+ h5 h2 `; U. O
1 d% A& ^& L3 | 8 y& X; _1 c! @ Q
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
0 R+ A5 w4 N8 A. r) g f$ k
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
" _; u3 R7 h/ P* Z- y+ w/ K. B2 ~! e 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
& v9 J$ {& e' l! D, D# t; F1 R
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
; o% z; q" n4 F- e0 ~5 _' x 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
% \" a8 u1 b# B0 p