U: ]8 _! X7 l8 p' R 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
p2 S3 C/ v# ~& L
7 R9 e" I" V* z$ E( e 使用方法很简单,操作如下:
导入包,创建一副世界地图, r, A5 \5 N% J
import folium
# {' i4 a$ a, f6 K* _* H import pandas as pd
1 n, B$ f* L0 o- n) Y2 A
* G' Y. A+ C9 }% h # define the world map0 K9 U; c, G4 d! Q8 p9 Q% j, ~7 u ]
world_map = folium.Map()
; K1 Q& @7 B. @, q
4 Q' V: B: O& t& [+ x5 q # display world map
1 X0 M! t; u0 W/ n world_map
. E6 Y' g! A1 \
1 Y2 I1 ^+ n, u1 c" V# S, ^' p 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
4 { U+ @/ b$ t" @ c2 T7 z ? # San Francisco latitude and longitude values
* J. o O j: W latitude = 37.77
6 @+ z7 X! n% N; F, F' U t longitude = -122.42/ Z. h' A3 I! s$ p \3 D5 G( G
) C) ?- B0 ^, |6 `$ _
# Create map and display it
' W l0 a0 A3 o) ]9 H3 Y san_map = folium.Map(location=[latitude, longitude], zoom_start=12)2 N7 F5 W6 ^- U4 U' \0 G2 P
: j2 g! q3 f! ]6 [ # Display the map of San Francisco
3 \. ]/ [0 U/ K+ `( W san_map
, n3 d4 h/ j0 r6 d9 b
: K5 Q6 j1 ^9 k5 d8 p
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
# \7 c2 a3 N7 y+ D+ m( \
# Create map and display it7 t! x/ n. }( l U1 o- E
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) ?5 ^2 k3 f% z# W6 a( y
7 s' K$ j& w4 B3 a/ u6 m! t
3. 读取数据集(旧金山犯罪数据集)
; x! Z2 j; d7 y( @' Y
# Read Dataset
2 _/ A0 S3 `, T( p$ X T P- {1 k cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)" Z% P$ o; R* i9 G; ?
cdata.head()
$ z/ k) M, z; g/ X* }9 f8 t/ _ ! K4 W0 e. C9 K+ f' Z I
4. 在地图上显示前200条犯罪数据
" s4 _6 b2 g2 w2 j( m1 G
# get the first 200 crimes in the cdata
9 U$ ~( t2 Y, P# N, m
limit = 200
+ M' {* [. m7 B+ y7 [5 |) I
data = cdata.
iloc[0:limit, :]
T' q& G5 g4 V) A: W6 S% p0 Y% F% A3 @$ _! V2 {2 ?" r
# Instantiate a feature group for the incidents in the dataframe
7 E- |5 d: g+ Q0 F& D% }5 M
incidents = folium.map.FeatureGroup()
7 K" c6 x d6 S/ a! Q5 S% ?; Q
/ |0 W/ [ v( Y9 J # Loop through the 200 crimes and add each to the incidents feature group
^6 Y& b# u# k ^- R
for lat, lng, in zip(cdata.Y, data.X):
; a% U R4 y. |% j7 J1 |% b incidents.add_child(
& J3 o2 }- x9 \+ a0 y" M
folium.CircleMarker(
8 p: N+ v' c$ H2 k* x F [lat, lng],
. i. s' p7 W2 s+ a' r- ^# s$ K
radius=7, # define how big you want the circle markers to be
$ z8 a* E* Z9 {) V. V' h- k color=yellow,
9 V) m) j. X$ Z
fill=True,
, t7 J# k, }2 u* B# l
fill_color=red,
9 \3 c9 h5 ^( i$ J o% {4 q" d) p- H; g
fill_opacity=0.4
1 r. M6 n' I, I4 x% Q, {6 O )
8 g$ \% j* K/ |3 E )
6 t- k, B8 E1 e+ R# n! a% Y- \2 }( s8 Y7 T$ x
# Add incidents to map
2 Y, e( M0 [# g! F. a Z$ n6 B
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
+ C9 x3 I4 `/ e9 A san_
map.add_child(incidents)
+ H- p' v$ R# I
$ `% L: v/ }; x J/ h( x8 ]6 f
5. 添加地理标签
, G, T, o; F4 @' E& h+ m# m0 @
# add pop-up text to each marker on the map
' D. o* ?! ~. |" U: w% Y$ D
latitudes = list(data.Y)
0 V/ `; q, b! r4 G+ E. Q
longitudes = list(data.X)
U) T1 T- \- r# l$ H- w& e* {6 f
labels = list(data.Category)
; T7 N) D( o* v% ?: l
% p4 {- n- f- e8 t4 I3 q/ ^/ C for lat, lng, label in zip(latitudes, longitudes, labels):
8 {1 q; s+ v( j! r
folium.Marker([lat, lng], popup=label).add_to(
san_map)
& b a. g$ p" t4 ?
# X4 f. w, T7 ^) E5 P$ P! c' G # add incidents to map
. ]9 `0 z9 A' Q san_map.add_child(incidents)
5 l- G( g7 ^3 H& @( O& H% X. \" I 3 Z3 R+ L4 [/ _3 E4 p
6. 统计区域犯罪总数
& F% i8 P# L) G9 e3 b7 K! x from folium import plugins
4 b# C( \- m1 W% w X
$ e+ r! A) |2 [
# lets start again with a clean copy of the map of San Francisco
4 `$ j+ s/ e9 o% T# s4 ?
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
( |& r: c' S \, V. O! i
% R8 U5 r' A0 s4 y7 o- E
# instantiate a mark cluster object for the incidents in the dataframe
4 Y4 B& e) ? h. @; c* \4 H, l incidents = plugins.MarkerCluster().add_to(san_map)
; k U2 L. Q" [# |' I3 z- w2 a
+ {9 e+ T& a7 A8 L; u # loop through the
dataframe and add each data point to the mark cluster
3 ^4 t7 z1 N* }/ y+ m/ T for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
2 l1 ?1 U& r! P2 T* j' G
folium.Marker(
* w- a8 f9 q, _8 G' r location=[lat, lng],
3 l- _( H/ J/ a/ ]' k/ z
icon=None,
+ H# g3 Y0 m) |1 g popup=label,
: X6 w; A+ `$ P; r; \) `
).add_to(incidents)
/ A6 s1 b9 W" G) y3 h/ k
" }. F* C, V. K" H( V1 E3 T
# add incidents to map
1 z. c% [$ M' r7 Z3 A
san_map.add_child(incidents)
/ ]5 A% d# m) p7 e! U2 \
& Z: H% F9 @8 K5 S& o4 {' u 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
6 \% m" W! h) l" l( h% S: i0 B import json* M x9 @' _# i3 ?; b f7 j; J
import requests8 G; Z0 P! X3 I x+ y4 g! M" F
1 R* g6 G5 e) l- o% M6 C url = https://cocl.us/sanfran_geojson
8 L2 P7 G* ]9 ~ san_geo = f{url}" ] ?2 c2 g: _& x# n$ m
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)) s6 L4 W, A2 q+ n$ |. `
folium.GeoJson(
/ o8 \" Z& j$ p! \+ P9 ~. f san_geo,7 \9 q8 I5 H" F# n8 E! p/ Y% o
style_function=lambda feature: {
/ v* Q- N, Q0 d) n8 @! x( j fillColor: #ffff00,
5 H! U4 i+ w% j' z, E color: black,
& E$ D% p% z; _, o+ W9 U- X/ m weight: 2,0 L( t; O I9 O9 N! g+ m4 c
dashArray: 5, 52 k+ ^0 }( o9 [2 i6 }& o5 j+ \
}
+ b( w0 N5 V4 a! J6 k. I! K7 J ).add_to(san_map)# Z. d4 m2 i: p# T
: }5 }0 l' a* F3 c4 I% m0 _" b #display map0 _8 \3 [, t% C' j% O' S
san_map
% K: ^( y+ `7 C ' |" D! j* _' ?/ W; t3 m. ]
8. 统计每个区域的犯罪事件数目
1 l$ S" c& C: c- c( Y
# Count crime numbers in each
neighborhood* h: n0 L( I! c# L2 X+ j
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
' K' x/ V- K9 q& @ disdata.reset_index(inplace=True)
6 ]$ b2 z3 J* ^+ V) t" R2 g0 T3 _ p7 B
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
' |; |$ f/ B- _! c
disdata
) Q7 d% H Q9 U {
! F) V$ C4 _0 Y! Z 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
( n+ t/ n8 [% E) v f
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
4 T+ z; W! {4 q ^- Z6 X
folium.Choropleth(
0 {" ^+ I8 D4 b* r geo_data=san_geo,
7 y3 o: M9 | ]" V" \+ L+ g data=disdata,
( u( c5 f7 T$ s columns=[Neighborhood,Count],
% O$ l2 a5 Q8 I* L- a; Y% z
key_on=feature.properties.DISTRICT,
% z) \+ l! V, l
#fill_color=red,
& C) t! U4 X8 r0 g6 P fill_color=YlOrRd,
- N$ p1 T' U8 o. M+ q fill_opacity=0.7,
2 s2 G u/ q9 k( Y; t. C! ^ line_opacity=0.2,
4 o3 X. m `2 r highlight=True,
% ^2 c; W$ l* o0 w legend_name=Crime Counts in San Francisco
8 \ t: _3 p% `3 u ).add_to(m)
) Z- l. a6 |9 W" z7 k: g" | m
7 w3 H0 y# b" M
( \: v( m: G7 F' M; j( i) X! p( q
: b) G5 c7 {3 X! \) N+ e' D
10. 创建热力图
1 m; v6 Y- ^# N3 z' ]" X/ d& W4 ?$ @
from folium.plugins import HeatMap
9 T' X# ?# A0 [! ^
/ _5 z6 f2 h( e # lets start again with a clean copy of the map of San Francisco! |; B6 G* F- A7 m$ ^3 V1 T
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
( D0 v# ^7 P3 J; J* q6 x+ n. E6 g; P+ X" C
# Convert data format
( w- v. C5 U* u1 f- Q5 A heatdata = data[[Y,X]].values.tolist()
3 I1 _$ x2 Z- T. n# A/ R3 Y! P5 T+ i' i& u" t& e6 p
# add incidents to map9 D8 @! ]7 ~8 i! ]; Q1 ?4 G
HeatMap(heatdata).add_to(san_map)( k$ f0 J \9 T( ~# l: B+ j" `
0 A/ ]( E" ~( ^2 | N: S0 v
san_map
, x# [$ @$ y4 \# y% u6 N% \0 o
- w0 ]/ U- V. p. z8 U3 w
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
, M7 N! ~( N/ v% S* c# f
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
+ ], |; b1 t. T" ]. F
& P) X1 s" W$ {+ q4 M# C ^) s
我的其他回答:
9 O3 j5 D4 h" A P # d/ @* L5 ^! ^5 c7 ^% o( Z% k
1 V3 J: q+ p0 B: b
# s# u7 q+ M# k" T 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
* Q- D" M" j: |- n7 t3 g 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
) G6 g' p7 u1 l/ R 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
6 }. Y" u r) }7 @& v' ^ 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
/ C/ a' M, t. i& T6 J; Q; F
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
: M4 s6 o# {9 s3 [% K/ C) V