7 P$ S8 y- a& ]
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
/ |0 B2 ~' M* T$ d3 e5 q" O Z
! i% \6 b* A1 W, i" ^$ t" Z 使用方法很简单,操作如下:
导入包,创建一副世界地图
) D W' a" f3 i, ]4 ^ import folium
/ \' \7 _7 |& o. s! v import pandas as pd& f% R# y; B+ n+ h
4 f" p7 M* Z, `7 x3 l) U% t5 B
# define the world map; {0 o; D" h3 ^) ]: l' h
world_map = folium.Map(). Q$ J3 g l* X, w& F! B$ T" Z' P
% k0 X0 i; y! m) r # display world map' }0 s. N3 ?! Q C- D% K/ N
world_map
9 s8 m% o5 o0 p* }; u# `, R9 {/ { u
/ n; E0 V/ s5 R w 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
8 p9 v' y6 @' b) T3 W7 J1 |
# San Francisco latitude and longitude values
" H4 P/ ?" [! y* T# E latitude = 37.77
0 }2 X: k' ?' a9 w7 h/ t longitude = -122.429 @4 n* ~* s; L1 Z4 F
; @1 z) G$ M8 H1 c! a( Q! C; f. Y. d # Create map and display it
, ~7 @" \+ v* z0 E# @2 [% k6 { san_map = folium.Map(location=[latitude, longitude], zoom_start=12)+ R; H. j) b7 q r3 I) u4 l
- W5 j9 W4 \ g, O7 q# s1 z # Display the map of San Francisco
. Y1 {5 _/ G- [* b" [5 F! y san_map
3 A: ^" P) G& o
6 X( r! x9 E2 C 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
" Z+ a+ T; M) { P/ d6 N
# Create map and display it+ c" }. q# X- P x6 b
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
! x4 z* E5 i3 \5 d- [
5 F+ d- a- h j6 L 3. 读取数据集(旧金山犯罪数据集)
0 t6 @" a0 D' u6 Q: L: _8 P% M
# Read Dataset, ^& P7 F3 e; n) `
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
; w6 W, A, v* Z$ J" u/ V/ l3 o cdata.head()
0 d' K! b1 j3 s% P$ r9 ]6 H
+ X. d0 j- v. v% @! e6 G
4. 在地图上显示前200条犯罪数据
. Y* q/ o2 F! `# n # get the first 200 crimes in the cdata
9 M$ l: ~/ \2 n0 Y5 _2 r! R
limit = 200
5 j$ t' L* d2 o" n" K data = cdata.
iloc[0:limit, :]
8 H4 W3 C( n" s" T" T8 w; ^
7 O# O0 `) ]4 t/ w6 a v% Z( D* o/ m
# Instantiate a feature group for the incidents in the dataframe
1 P0 ~+ S, `' r; u6 h incidents = folium.map.FeatureGroup()
$ p7 o$ P2 w; d1 x6 I* M- [5 g: U# [+ b1 B4 }0 M
# Loop through the 200 crimes and add each to the incidents feature group
) S8 E8 ?" S1 g* [' [0 H: x2 E for lat, lng, in zip(cdata.Y, data.X):
% E* ^/ ]* x5 {' h incidents.add_child(
* d5 L$ e" X$ e; h( W: `7 u% z folium.CircleMarker(
! B& |2 j h$ z) n5 ~% q; i* ~
[lat, lng],
; [" Q5 e: N8 z
radius=7, # define how big you want the circle markers to be
" T4 l } ]& H( o# f5 M
color=yellow,
& ]4 N+ `: r+ E% V, H* ~
fill=True,
3 @4 i2 g j4 T# a3 f
fill_color=red,
) y$ i' v3 i9 y4 A fill_opacity=0.4
1 N6 R9 J. F$ z3 @+ t$ S7 {; T
)
5 b: @0 j; p1 d! w+ a3 N# k )
; s0 l5 e* a4 ^4 {, q; ^
& q/ s2 i/ f' W& c9 f' C; T # Add incidents to map
; q. `& w- y& Y san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
, X1 Z5 {, N' D san_
map.add_child(incidents)
( l; \$ P0 B! h' \: o
1 \4 t0 S4 ~& U) G; Z" f. r
5. 添加地理标签
* `" Q; H8 D( B8 x1 D0 k, O # add pop-up text to each marker on the map
9 t2 n& s% @% A$ A) |; L
latitudes = list(data.Y)
/ O4 W/ D2 v' U) |8 r. s2 y, [' T
longitudes = list(data.X)
. N" z0 P& u5 N( @ O% b labels = list(data.Category)
" @( o) R$ F( Y: w4 y2 W9 Y6 P" x
& V h. E2 W R+ ?- } for lat, lng, label in zip(latitudes, longitudes, labels):
, u6 Q. e4 d: p# E. J9 D2 ~) o
folium.Marker([lat, lng], popup=label).add_to(
san_map)
$ @# W z; O0 R: x9 r8 I
+ B$ X" F2 Q/ O1 z: z) {8 m
# add incidents to map
; M. m# V# s* b, U
san_map.add_child(incidents)
! r1 A9 Z& y3 k& k1 B
6 Y3 D) q6 Q0 }2 q% J 6. 统计区域犯罪总数
3 D# ] m z$ L0 E( \( p( I; k3 g from folium import plugins
9 m/ o7 u8 n4 r8 [6 L' W+ J, o( j1 _0 Z5 H% q: k4 b% E+ l, c
# lets start again with a clean copy of the map of San Francisco
]* n' p \+ [2 n! `6 W
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
0 \3 Y: c" h b
( Q/ H/ c! a7 N. M; E# ^* o4 h
# instantiate a mark cluster object for the incidents in the dataframe
, a9 E" d6 Z" p' Y# H: ?- T! f7 p: e incidents = plugins.MarkerCluster().add_to(san_map)
9 g, }6 {1 O7 ]2 n; X* l; D' K
% a/ q" I0 Z, Z# Q( M9 { # loop through the
dataframe and add each data point to the mark cluster
9 L3 A# n( ^+ c( f# F for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
3 } s+ J3 J$ t9 w folium.Marker(
* n% m5 @7 Q3 `/ ^8 f" d location=[lat, lng],
! @8 {& E3 V8 v icon=None,
: {$ t0 h, y& R; S0 k0 \6 Z( X. ^
popup=label,
, L0 f7 |0 K* D& b
).add_to(incidents)
* X8 j" w. [9 K' j
1 D* O+ @ K: _( }7 v2 C" M! n9 o& v
# add incidents to map
: W3 \/ b, ^( ]1 W! ?" V2 F san_map.add_child(incidents)
- ^( X" H2 g4 H& `
+ K% ~( P! D- U9 g" R: t; B 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
. V+ |$ ~, h$ g; L import json1 p, M& p/ h6 O7 P! m
import requests
/ a% p' B/ t2 O% m2 w+ _
- f7 M# d1 G( I url = https://cocl.us/sanfran_geojson; B% ?) P: l0 U" m9 @" z
san_geo = f{url}& R0 V" g( ^, H6 s% `
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)6 [. k5 `; q( ^& m) F
folium.GeoJson(
# ~: ~, ?9 s) a0 W9 ` san_geo,5 y+ A6 G4 V9 b8 [" d4 e4 X
style_function=lambda feature: {
: R' F! B9 T8 F* _3 x fillColor: #ffff00,
( `0 s! T: M L9 E1 b color: black, j! P" W* S6 {8 M
weight: 2,6 d. q0 o# @3 }0 Q3 o8 q
dashArray: 5, 5
- J( X; z; I) x8 @' X, x* u }
. K# C5 w' {) b l! F ).add_to(san_map)0 W, i( j# n) ?/ i
* x+ J4 \1 ~% s& @9 n5 X: d
#display map8 ?" i \" ]$ w
san_map
% S: H( ?/ c0 G- ]8 ]% r" b
% N8 R8 Z1 T' L* W U9 K 8. 统计每个区域的犯罪事件数目
+ E8 ^& k- e& H$ O # Count crime numbers in each
neighborhood
5 }9 w! d% @( [, d' H' C disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
+ y1 R1 L2 H' ]/ e
disdata.reset_index(inplace=True)
7 L. D* |/ @; P6 x/ R% e. G) [
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
! j' K+ g6 U) t: Y. z9 L: F. T( ?
disdata
$ [2 \" Z1 A b+ Q2 P0 G5 G' o9 e# s
. t/ B8 u. h& _1 w& w6 m3 H 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
% U: Z0 |( g, m6 A m = folium.Map(location=[37.77, -122.4], zoom_start=12)
4 A( N/ t x, C* z9 @
folium.Choropleth(
3 n4 N( J7 ~3 ~4 T. _
geo_data=san_geo,
1 v8 p- f" _# u data=disdata,
* X9 ^# q, @- d: X# R; h/ M" D columns=[Neighborhood,Count],
. C6 l! u/ N, w. a2 e
key_on=feature.properties.DISTRICT,
) z8 a7 B5 X" u! H L
#fill_color=red,
4 ?( H" S6 ~$ _: ]- c7 T0 D9 N fill_color=YlOrRd,
I$ c: N* s% ?5 \3 v' h h fill_opacity=0.7,
; e0 F* I' b6 s% F8 }' c& C |* W
line_opacity=0.2,
+ b* ~; x* o8 w1 {
highlight=True,
: D! x4 E1 o) g legend_name=Crime Counts in San Francisco
) B2 L% D0 U' c0 \0 S
).add_to(m)
( K& B9 h6 j2 o" [( z7 ?
m
2 E. ^$ D' {- S" Z* N4 ]* A' L 1 b% y$ v( h0 L2 [/ ~$ t6 S
V7 \7 s* A, Z1 W 10. 创建热力图
& J! G! a7 N2 v9 R' C
from folium.plugins import HeatMap i4 X, W' T3 |) B# q
1 S# r+ k8 |4 r& O# u
# lets start again with a clean copy of the map of San Francisco
4 i' Q7 F, [. e san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)6 Q1 x$ p9 {9 ~2 M7 D
& Z, @4 ?" l# m! {) ]/ D9 \
# Convert data format4 i( F3 {5 y: F9 O0 @3 k
heatdata = data[[Y,X]].values.tolist()3 M" d6 B! X) ?2 |$ Q. W. _
# |. Y$ y4 y, m h; s4 y& i
# add incidents to map
; O9 g1 {( W% ?' Z9 P HeatMap(heatdata).add_to(san_map)7 d* g0 T7 O, X- M+ O; u
2 a" e& ]# }9 V3 L: v
san_map
' h3 u( A! r* F; z: Q( l( {' D
* h% p, b2 ^) D' U8 Q& V% Z% J 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
5 b8 c" Y# T' y4 l 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
0 A: H0 \, L; ]/ [9 A( u n
' K7 X% m; _ j) Z 我的其他回答:
) h! F1 s$ d5 ?6 M$ d 9 g% Z8 H. i( S- O' b' y5 h
, }$ F+ N ?+ T9 M. H O6 l. p 2 L2 ]# S0 b+ G
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
; A4 j. I' t8 M
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
: \3 \0 T: J9 r# W
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
1 I8 o% L1 p+ q- u" _* Z1 r8 Q, ?& S
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
8 c1 {; x) V. A4 Y 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
& [' W7 b* y7 V; p' z7 P