' p7 p) w8 h) b$ s0 p' w- @ 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
9 L. I" H" b( a/ T3 p" y) l# b3 u
" i7 ^( ?6 k6 J" O8 q+ A 使用方法很简单,操作如下:
导入包,创建一副世界地图
7 r, O7 M7 r! D8 h5 k import folium
" D" b0 m. ~; s import pandas as pd
/ w2 k# H G% {* F3 ?4 x% k( a
& e+ M! n5 c7 d9 ~ # define the world map
}( t! G: W* J4 O- p+ Y world_map = folium.Map()) T7 ]( @; K3 |# D% D1 R; q. `2 w
& V, y; W! ^2 h6 d* ?6 _
# display world map
) Q# w* i1 c0 T0 @ world_map
3 Q7 V9 r4 N9 S 5 Z! m! ^. n) Z; V& W4 U' |8 G
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
# ], v! d( R4 x/ Y. X; N # San Francisco latitude and longitude values
9 s9 [' z% c* y9 Z latitude = 37.77% Y0 N- t- c. {/ O8 r8 u8 |/ [
longitude = -122.42- g- I- x ~; w8 p) u% S
. s+ J m) y1 b9 N9 {- [" I
# Create map and display it/ \2 i# ~( y8 J
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
1 k' z. {& j/ K( N
2 i' _+ Q6 @ c1 C9 s3 | # Display the map of San Francisco; G5 p5 m3 r/ f! [- w
san_map
9 c9 u6 D# J/ k0 }8 x4 A
) t+ u. Y: g& R8 w0 s* k
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
, t/ x2 t- b- { @1 C) ` # Create map and display it* C/ M5 `% ?, w0 o! d3 G
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
2 r2 i; I& ?" U% Y$ V
# y) i$ \0 o! o& b
3. 读取数据集(旧金山犯罪数据集)
0 L" h `4 p/ x( b9 r9 [- H6 w, p # Read Dataset
% Z: l7 T m8 ^7 { cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)# m" }+ `8 L3 i, l+ h
cdata.head()
7 |- K9 U5 ]- u( a+ `) p$ b
9 \, s) g3 k" F' T
4. 在地图上显示前200条犯罪数据
7 G. ?0 |* _( d! n% u" p
# get the first 200 crimes in the cdata
/ H4 E: G3 t: K8 o+ l5 b. x limit = 200
* b' d# \. d( L
data = cdata.
iloc[0:limit, :]
! x8 Z: Y( L7 l
" @; H E Z* g
# Instantiate a feature group for the incidents in the dataframe
/ J2 {& U) T$ M5 Q3 @4 _+ l
incidents = folium.map.FeatureGroup()
' u# c$ a1 X* M4 M# Q
+ j* ]: \, P. P% \ # Loop through the 200 crimes and add each to the incidents feature group
# p( d7 x* L' x- k
for lat, lng, in zip(cdata.Y, data.X):
0 s' |& N" a7 b& u* `
incidents.add_child(
3 ^5 ]5 L! ?* g& {) U0 _3 x: ] folium.CircleMarker(
" T7 @1 B# N* q+ `& O [lat, lng],
1 u, H" }8 j! B$ A5 [) R radius=7, # define how big you want the circle markers to be
$ w6 d; L9 T* O color=yellow,
+ w1 W& Q+ M/ X. U0 U" H, j fill=True,
/ q: p' z- ^5 q( |0 y8 p# \
fill_color=red,
1 i4 V* k0 S% Z% e2 o fill_opacity=0.4
/ b' H2 o5 o% D+ u; S )
2 G( C, s; T% g$ ]$ c* a )
+ P- C/ I. U0 R2 Q3 F3 | O
l0 B, w8 t% b # Add incidents to map
$ U" `3 |8 T8 d7 ]
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
4 F& V" Q2 e+ h2 t. h9 q( r- U* i: _: F( J san_
map.add_child(incidents)
9 u+ n" Y3 K. G
- w6 L& q9 ?" g7 Q: @4 v, ` 5. 添加地理标签
- K4 S; j. [2 p: X" _! u$ }8 Q3 Z( @ # add pop-up text to each marker on the map
1 Y$ i% I" n4 _( y# b
latitudes = list(data.Y)
/ |) y/ D- e7 q0 F z; H- A
longitudes = list(data.X)
2 p- f6 s) I1 w6 ^
labels = list(data.Category)
) Z, Y- Y' d, a* h" } Q& ~7 e* {2 s0 ~' I
for lat, lng, label in zip(latitudes, longitudes, labels):
2 A( c0 c8 G J& q- j4 y2 R/ A
folium.Marker([lat, lng], popup=label).add_to(
san_map)
( H3 ?: O4 ~( F* b4 |
; _$ z7 W( w, Z G* v5 ] # add incidents to map
( X2 `2 X$ J1 Q. N
san_map.add_child(incidents)
9 f1 y; f, i) Y. S+ R" j
# b4 T g7 P& U, |, l
6. 统计区域犯罪总数
/ c- h3 x) j% T+ q8 @+ C, Q from folium import plugins
5 [) ]- c7 H" D7 D% ]$ D2 C5 ?
! b6 ~+ {) a* v5 }1 O$ _ # lets start again with a clean copy of the map of San Francisco
& ~) Q. U0 C( e0 B% D: E san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
3 d4 |% q8 \2 P: a0 R4 G. d7 g! s
# `& I* e, M" Y' b # instantiate a mark cluster object for the incidents in the dataframe
8 _$ z7 n: n& `! d" ?9 e7 c incidents = plugins.MarkerCluster().add_to(san_map)
& N, ^3 H% q- t' o0 g
! p9 [; r# D% y0 b
# loop through the
dataframe and add each data point to the mark cluster
& j9 b6 [7 O' I0 I3 o) J; p8 c
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
- a6 R; x$ Z) `9 T+ f folium.Marker(
1 V: D/ L! X( V( C+ D( @1 X
location=[lat, lng],
$ r) E& \2 P/ K$ R" T icon=None,
# a3 [ o" k* X. r. k
popup=label,
" q) f2 q0 D% G; a
).add_to(incidents)
+ ?3 h; W, t& y' ^+ z
- Q3 G8 J4 o2 W0 Y. R+ _+ _ # add incidents to map
# U' \+ f# H- [1 ^/ e" `4 g$ S: x
san_map.add_child(incidents)
+ j2 d- a a' }
$ N' E6 y" w3 T" g 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
4 Q; p k" |7 C9 E5 e$ E5 \2 R" M import json
% T; V: F) F0 C6 w+ q import requests
- A# Z3 P `6 h C6 D, n$ [5 r, o8 K, e! {* c
url = https://cocl.us/sanfran_geojson1 d( U7 P0 L" `& d# m' Z* P
san_geo = f{url}& k0 A4 G# ^6 O. C- A- ~, y; |: A; q
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
' P7 ?) J7 |- s7 i4 D folium.GeoJson(/ a; p" t. O3 p( d
san_geo,' B. E4 @. @) Y8 j- Z+ {
style_function=lambda feature: {9 U6 B& n- n% g; a) B" T! [
fillColor: #ffff00,% c* e3 n; F1 B$ E% M7 ]
color: black,
8 C: `7 W7 j2 l! P0 ~& G- Z" m weight: 2,
/ B' x4 F) l) I. s+ [ dashArray: 5, 51 g, V! `/ x- e1 A
}/ ~! E3 \& I7 i1 @6 s
).add_to(san_map)
, k( x. w. Y0 n; e. f2 D+ a! C% Y7 P/ i* q0 z
#display map' z& J1 X8 B. L4 j# m0 {
san_map
0 z0 ]; c/ L. p8 ]3 j4 U
/ G: d4 K8 P9 H5 E" r
8. 统计每个区域的犯罪事件数目
7 r& F+ s( B. ^& T+ } L6 a3 l, t
# Count crime numbers in each
neighborhood
3 |5 Q* V3 w1 A disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
$ E( x) e& a! I" c) B6 g( p. n' t& Q disdata.reset_index(inplace=True)
: L- q* |3 l, O4 U+ I8 `3 ~$ G
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
% q: h" p0 P; A
disdata
# G- r$ I/ V6 f: d , P0 l' w% i/ d( o
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
# \- ~' H: e! F+ [+ r m = folium.Map(location=[37.77, -122.4], zoom_start=12)
9 @/ V" l- } K; ~" J folium.Choropleth(
0 i& ~5 H: o3 `8 U/ F
geo_data=san_geo,
' X" E( x8 j' g) F# y; b
data=disdata,
1 Q) c; }* ~" _9 r: @( ]
columns=[Neighborhood,Count],
( S. K0 E% A9 {; N
key_on=feature.properties.DISTRICT,
7 E6 w/ e* |& v8 H3 O9 W& H5 C #fill_color=red,
+ r" u& m% T/ c: T- c fill_color=YlOrRd,
' U B2 ~) H, @" M& K7 c# Y fill_opacity=0.7,
: y( U- ? g% F- r line_opacity=0.2,
& Z5 p0 D8 ?8 x l
highlight=True,
! h, o% }* @7 l6 G8 }8 R3 v1 O legend_name=Crime Counts in San Francisco
: ]* E2 R: X, w
).add_to(m)
4 f+ Z' `- ]# _
m
6 K8 K, |# N5 j% O. T2 y6 N
2 Z1 t' H. `# m/ S, B
# M/ w, i3 \+ ~# X( b
10. 创建热力图
0 @2 c, j7 a/ `) K2 {# v# S' n7 r
from folium.plugins import HeatMap; S: T6 _0 N0 w- I
6 K" d: u I5 f" ]
# lets start again with a clean copy of the map of San Francisco* K: V! T# }/ y) u$ x2 X' C
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
' |1 e+ r4 \- E4 ]2 T7 i/ E- w) ~1 W4 d) L. i, b! Q
# Convert data format
3 r$ u5 j& A0 u, e7 G heatdata = data[[Y,X]].values.tolist()
+ }' m6 q2 l' Y) B+ O% J
; H* O/ _* e) I) `# u # add incidents to map
! K! Q8 L% G( O* t: d HeatMap(heatdata).add_to(san_map)+ y5 d: L: n% ^! [0 F
* A' ~% z( u. N
san_map
1 j0 h; ~+ s9 C6 u) I5 w. o2 G
" O& ?& e, p5 K( ^
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
1 z! p6 L2 s) K1 { c
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
$ z, C3 A& [- R 1 Q! C3 V/ c P6 `, [! a" i: _
我的其他回答:
& B: c4 L5 z- b" w) `/ Z ; ], k6 l+ W4 o
+ ^" i& u% j, j0 X) T2 u
) V8 D$ `" a$ L2 V: I 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
9 Z: [0 Q% {$ p% C$ g# p1 ?5 R
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
6 z. w0 S- }+ Y8 u' N 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
9 r& V5 T$ u2 L$ S/ g0 G
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
! M3 e7 g* R7 B 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
0 U+ e" r/ h7 o8 ?; Y