7 t: m7 E3 w7 D0 h# s
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
- g- ^* D& j0 K3 J3 o/ r5 u, D
$ J: U$ p9 w# e4 j& p ^
使用方法很简单,操作如下:
导入包,创建一副世界地图, F1 p# [% t6 h* D
import folium
t- U1 z. A4 }- n; ? import pandas as pd6 F' X/ P/ @2 a4 c t
) D4 W; B4 U6 d% U
# define the world map- D# r$ f6 q, q+ u
world_map = folium.Map()/ t; ^9 ]( e. U* d3 C' M
4 s* K1 B/ \2 Q9 G9 N: Z8 J8 o
# display world map
, l/ b6 O2 W' B) Z world_map
{/ N, K% e, c
6 t+ Z, k! f: R2 q, {& f6 E7 v
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
$ v+ I, z* V% D2 c
# San Francisco latitude and longitude values
! T/ d6 C8 J. _ z latitude = 37.77, b) n* Q& r1 |0 i; [! d
longitude = -122.42
/ n6 c1 a) O! S3 f- u" V5 f7 h. _+ C3 t; x
# Create map and display it
% |, x) A+ d5 F6 z6 \8 H, B san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
5 U$ M# o3 R- H. A, h' c% m6 _8 n, s# p0 R" x
# Display the map of San Francisco1 E8 W" L8 f. V; q0 F: @$ p
san_map
d: G. p5 S0 ^: c & O5 {/ d5 j# M3 B: x4 }8 ^ V [
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
" \& }7 p% @% J3 X. g3 q # Create map and display it+ {) e( R: u* x% f
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
, F6 l/ X7 d' B8 g2 F' k : W7 G/ k1 C# ^2 G2 u4 L
3. 读取数据集(旧金山犯罪数据集)
4 P5 B. j- s- i1 ~/ |2 C# {6 _ # Read Dataset
# y5 Z$ P+ J& {0 h4 b cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)! L0 Q! v! @6 W! c
cdata.head()
4 ]! i0 _( u& q f+ }$ R$ j
' A6 V' Q( e* T1 M9 S. w 4. 在地图上显示前200条犯罪数据
- F6 ?* n+ Z$ U5 S! ~ # get the first 200 crimes in the cdata
( X& |! y- {, U# t* N( m, G limit = 200
- G) G W) I( p6 z4 ?3 W
data = cdata.
iloc[0:limit, :]
9 g K$ t6 u6 g6 l. h( Y5 w; o
$ f" p1 |" t' X+ }* U# U8 l
# Instantiate a feature group for the incidents in the dataframe
m! ` m( e5 [! C8 ?/ E0 v incidents = folium.map.FeatureGroup()
; W, X3 g( j; o# ~, o
0 w% X0 L5 {- P3 h( l # Loop through the 200 crimes and add each to the incidents feature group
9 A. s5 f: }; P& w
for lat, lng, in zip(cdata.Y, data.X):
+ _+ _$ ~0 M0 f9 ?1 [$ C& N( _- z1 N incidents.add_child(
4 \0 P3 q2 L# @/ O/ U( L$ T folium.CircleMarker(
5 n7 ]! B: \9 P ]! f( B! } [lat, lng],
7 l [9 w% }4 `, Y; G* T) h
radius=7, # define how big you want the circle markers to be
) ?6 n: ^% h0 o color=yellow,
7 v0 _1 y0 c& s0 J8 i5 B fill=True,
/ F9 t2 k8 O- F! F' o0 D4 O fill_color=red,
* ~9 v" U# G2 \; O
fill_opacity=0.4
0 J1 |# U, `0 V& P1 Y1 x- e )
& o" e. D5 ?+ }* W; v( N! q
)
0 I: g+ Q$ f6 `: [' l8 l: z7 @5 m' J" f; a2 T1 ~
# Add incidents to map
% ^7 ~; g# ~" S4 M- {/ F$ h6 E( P san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
% S+ ?% _0 `% n, G/ r9 _ san_
map.add_child(incidents)
, m3 A- Z- U5 a4 B2 T5 b& X. e C/ E n- ~. P/ z: z$ n4 O
5. 添加地理标签
2 b5 g( i2 Z5 l) f7 t# J" p/ \
# add pop-up text to each marker on the map
) F# x$ Y- ~1 w& B: v) M6 V* U
latitudes = list(data.Y)
% a; r4 u& d9 E" A% l( J longitudes = list(data.X)
' S2 s, l( Z2 ^4 [ labels = list(data.Category)
1 ]1 w2 R9 }% B) |
$ N6 }% v" c/ G( b1 L' g$ {# h for lat, lng, label in zip(latitudes, longitudes, labels):
X: @) @' y9 U( w7 K4 h1 {( P9 G0 j
folium.Marker([lat, lng], popup=label).add_to(
san_map)
" g9 ` d0 f+ r# g& @3 [1 h) T, }% R1 K r) c
# add incidents to map
* `2 h1 X J! n
san_map.add_child(incidents)
% Z3 `6 ]2 M. r |7 M 3 T. G% F, j8 ^
6. 统计区域犯罪总数
6 J+ ^+ z2 a# V( L5 p3 G
from folium import plugins
* S! F' Q. [1 y9 T9 W6 s
; g8 A- I8 y0 W4 j0 X # lets start again with a clean copy of the map of San Francisco
; G9 Y( o& E* T4 i: ?9 G8 h san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
6 `* D3 Y& {: i: c" x: v
: y( N+ O/ q+ y. o7 B5 t/ Q, A # instantiate a mark cluster object for the incidents in the dataframe
, v0 P4 i. s! c6 U! P
incidents = plugins.MarkerCluster().add_to(san_map)
( s2 _ @3 x: m
4 }. `) C7 W( D # loop through the
dataframe and add each data point to the mark cluster
' x( o' e: ^! N1 w for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
- O3 u6 F, P. Y0 Q, v folium.Marker(
0 p I. T5 A6 p) Q location=[lat, lng],
1 ?& ^( d3 ]# r* V7 s" B
icon=None,
( p6 {5 H) ^/ o& F' d+ Y
popup=label,
# T x9 I% C, d. D* m8 b ).add_to(incidents)
7 y# {& }, Z Q& }
% \# W& }9 N5 B# Y # add incidents to map
5 O! O0 W% `# T! F; \
san_map.add_child(incidents)
3 g9 E. P- t- d* C0 S# y
/ a; ^' n9 y' u; v* a; K0 t
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
2 V6 r: U$ `. l' O. F
import json
% H" B3 o) |: O; _7 e) M import requests
( D1 w$ c3 i2 u" m5 z6 w. W0 l
* F6 Y, r# L* _4 H/ D1 ~, _4 V \8 m url = https://cocl.us/sanfran_geojson
/ ?. T8 V# L5 a- ~ z/ P! J san_geo = f{url}6 n' F; F8 C* e" C3 ]! i1 B- T
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)* C6 q6 E' i9 A9 A6 |4 L% {2 p
folium.GeoJson(( G, p* d# X0 W; j0 V
san_geo,: X, Q) M: f0 k$ |! f0 h0 F
style_function=lambda feature: {
3 O( |) j/ D/ E. `0 i$ ]. y) U! g fillColor: #ffff00,
2 z1 m9 q) u! t2 o# Z- _ color: black,9 n: H$ u. m5 F0 j: S* s
weight: 2,
* j" ^- b) t/ |$ k3 d( J, L dashArray: 5, 5; ^, [" F" X& b0 ]) C
}
+ x% Q1 }' T" v5 g D! J ).add_to(san_map)
% h' O. H& y9 \" h c
' l" ^( k8 Q$ d0 k #display map1 |9 |5 Z+ b* s2 m
san_map
8 q2 ~( P+ Q" y7 x
% w5 b, e! T- I- s. I8 J 8. 统计每个区域的犯罪事件数目
% n/ P$ y! M/ x3 E2 S: X
# Count crime numbers in each
neighborhood# u( s# J/ t" t6 R
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
( z% H$ `0 i6 F6 i0 c+ V/ Z
disdata.reset_index(inplace=True)
/ n1 Y/ f4 A* \& u* j. M disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
0 Y: ]8 a: d1 P- y disdata
/ V2 {3 a; @# N$ h7 v
2 E. `8 s% V& J/ U 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
5 M6 t3 w- P: X$ h m = folium.Map(location=[37.77, -122.4], zoom_start=12)
6 T; Z, T! \& G folium.Choropleth(
# v% c7 |1 s9 j4 C9 j6 M$ p; P
geo_data=san_geo,
7 @; |9 V. j% g4 L' ?. Z" q8 M8 F% P
data=disdata,
7 h" C8 H! ]8 L8 v/ v3 W* o! v columns=[Neighborhood,Count],
" t7 C1 e1 U) ^5 Z, _
key_on=feature.properties.DISTRICT,
5 h1 w/ H1 G0 M7 j; Z
#fill_color=red,
' E6 B1 H7 {- Q" E fill_color=YlOrRd,
# [5 o2 w1 p3 h/ p) |
fill_opacity=0.7,
! X0 ]7 j& H' c0 ~" e0 o6 L, p9 ^
line_opacity=0.2,
% T; Z: k7 T# }1 j' D9 [% y& }
highlight=True,
5 L' O. G$ e$ ?9 @
legend_name=Crime Counts in San Francisco
2 Q2 k# I) g* A4 d7 q% d( `
).add_to(m)
$ S+ J9 V$ H" C m
; I3 N9 G( `& k6 u: M3 `. h& B) b
. {/ u& M) X' U3 x+ X, M
6 R5 @3 t. G8 U2 x' k, s* m 10. 创建热力图
* @) A& q5 f% t7 w& q
from folium.plugins import HeatMap
+ G0 a; \6 D3 j! j
_( j$ ]# w& H4 H8 `" C+ _ # lets start again with a clean copy of the map of San Francisco) P6 g3 z2 c' d3 d4 ?
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
# ?0 ^' |% b% C; d. S$ e. U; Q; `: G" z" w3 R
# Convert data format5 L6 p1 r5 Q+ @2 b2 t
heatdata = data[[Y,X]].values.tolist()
% v% T) `) `" W# m% ?4 n; z
# u+ s; Q! L1 N8 T" ? # add incidents to map7 e' F+ ^6 Q: M/ P5 G
HeatMap(heatdata).add_to(san_map)
% q4 A7 X, [' l, C, I6 C& k4 X! s1 W# l/ x7 n
san_map
- Y! l6 [# Q; G$ M- q. @
5 ?, J5 N1 P0 @! \! k0 Z6 V1 a
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
$ k: |- v. l( C5 K
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
7 |7 f* O- ?; N
$ w4 Y" g2 C. c4 w; C 我的其他回答:
' O# O8 v& b" k# k, j; @ + e ~; d; P- E% Q. ?
% a- F4 v& x4 d. N% m! m& H; M1 s & T5 Q. G0 X0 b9 s6 _9 n
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
. _6 Y, t7 ?; `+ C' u6 K; | 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
9 x6 E/ l# S* d
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
5 B3 V- Q4 H3 t3 E
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
2 h) i/ Z; b- r- s6 j
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
) G' k) \' j8 K: W