' t) q' `5 s9 A6 |# \) w6 X) O
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
. h( |4 u2 s" U0 V8 q6 b
9 Z' P+ m! ^+ e; u1 p% j8 H
使用方法很简单,操作如下:
导入包,创建一副世界地图7 D0 _+ H5 Q6 a* q4 k& @' _2 i
import folium" ?$ W; g5 G4 l2 J9 e. ?5 \
import pandas as pd* p1 Y! d+ @" Q4 s3 b$ e
$ |+ ~( \: L+ b6 P% C f # define the world map$ q; {- \( W; D
world_map = folium.Map()3 z. I- V7 ~4 S4 u* C; z) G+ P$ i% U
: x5 F; X" f% Z9 w1 b: Z4 B/ Z
# display world map; d B! v w/ B* {- s4 F% P
world_map
* f/ k4 h9 Y6 O# l- L+ L/ i5 c & z" a% q1 V, V" w
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
* _$ `" p% j4 t& Q # San Francisco latitude and longitude values9 p$ A$ L* C) B( p# [/ C
latitude = 37.77$ | g( N# [; a$ z: z9 C0 q
longitude = -122.426 m: j4 S. l1 @0 I2 H
+ \2 c/ W6 `4 J# E( s6 _
# Create map and display it$ w" d# t4 B; i1 C; } A* C* ^
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)! _5 t1 {+ u: |; L. H( G
0 \( E; h( z" L" P! r6 F4 V # Display the map of San Francisco' o9 c v* Q N
san_map
: g9 o# x' o8 {8 q0 B / S& _% B, D8 k, |% V
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
/ S8 O3 ?2 r! w
# Create map and display it$ V6 K2 J) ]4 e* [: G; x
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
! |. @ ]8 J& Z+ V, {9 r* [3 r
' T3 H/ K: I& R$ b
3. 读取数据集(旧金山犯罪数据集)
E) ~' I; P" v# y) c# g # Read Dataset
+ I7 X6 P( G9 k* n2 `8 C: r cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
+ q4 L: @* ?! p0 i" q cdata.head()
$ O9 x; A3 N/ |% g3 J! d$ F3 N l ! [( e/ j. q* u1 j+ d9 m
4. 在地图上显示前200条犯罪数据
- m, G2 e3 l2 I# Q4 q& m- t
# get the first 200 crimes in the cdata
8 w$ l- ] Y0 w" O3 ]& o* _
limit = 200
) S% Y8 Z$ p# r% E" Y" O data = cdata.
iloc[0:limit, :]
# ]0 E8 |$ R7 r: ]5 q! m, B- E/ c w* h. i: p/ y
# Instantiate a feature group for the incidents in the dataframe
" C8 D5 F J2 u7 Q4 \# n4 G5 { incidents = folium.map.FeatureGroup()
8 B* S, S& R1 v
2 k/ p6 A$ T( \* h # Loop through the 200 crimes and add each to the incidents feature group
! |2 S8 |; I+ l4 A8 V0 w6 k# H
for lat, lng, in zip(cdata.Y, data.X):
8 h5 `, c" K! P V1 v3 {0 n
incidents.add_child(
7 |: ]) ^7 w* p3 U! t3 B
folium.CircleMarker(
' G, _! n% G* d6 o
[lat, lng],
2 V' k5 j9 X2 d2 Y
radius=7, # define how big you want the circle markers to be
& N/ j( O# p+ V; g8 m) k2 ]# Z color=yellow,
( ]( F% ?1 P/ N" `7 }) d9 w
fill=True,
8 H( [# ?- i/ u' [" j+ V7 w
fill_color=red,
7 p M& Y% k5 i& X0 ~+ ?$ q
fill_opacity=0.4
% K8 \; n) w Y5 J% K7 [ )
0 {6 C" ^5 z, F* C. `
)
. t' q0 v0 V! x5 G" Y( Y b& `, ?
8 y0 a# l" O9 b8 ?0 E. i # Add incidents to map
; p: w$ N3 O* |, {3 [ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
' O$ f7 t" P! h$ j* J) a
san_
map.add_child(incidents)
- }5 A1 x& _) ?4 | \8 f ? $ W$ F9 ?5 p0 A& b3 G$ p+ B. H
5. 添加地理标签
3 A2 r5 C0 \/ U # add pop-up text to each marker on the map
& |5 m; w9 [. i" Q9 o0 m
latitudes = list(data.Y)
+ v) E3 G5 {3 \0 [$ {/ ~' a, Q longitudes = list(data.X)
9 m F, I7 w( G9 A9 p2 G labels = list(data.Category)
# o5 I6 C p2 l% o4 W- c7 a
. d: e8 X, b8 |% {$ n3 J7 _! H" W
for lat, lng, label in zip(latitudes, longitudes, labels):
; g2 _- [/ _% g
folium.Marker([lat, lng], popup=label).add_to(
san_map)
% N4 {) x7 ^) ^3 A3 ^3 B) Z$ S( \* a" a& N" o( f: m
# add incidents to map
% l. f \7 r2 d" C7 e4 _% @+ J% N
san_map.add_child(incidents)
3 C8 E. e& p, k U( H; P5 r' [( Z4 g
0 l. i3 O& N* z0 {$ ~ v 6. 统计区域犯罪总数
3 I3 ?8 d" u* g# J0 z) [
from folium import plugins
8 C* }! O1 I; O
( ~. X7 A7 I0 ]" J- f7 @" J # lets start again with a clean copy of the map of San Francisco
& ?! M0 \2 R- _. a O. b san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
# c' W- J1 m' U
" m* v2 y- [2 q* P+ R) r+ c
# instantiate a mark cluster object for the incidents in the dataframe
% C, y0 i! A, j5 p% {0 r. L incidents = plugins.MarkerCluster().add_to(san_map)
7 ?+ h+ E8 H x7 c+ n2 ^5 Q, W w- W; W( Y( U4 I4 J
# loop through the
dataframe and add each data point to the mark cluster
/ o$ M7 D; ]. W3 W! |' h* k for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
8 ^" p% `) H1 ^; ?8 j7 e. k+ N" q
folium.Marker(
6 R+ {' ?) a# \. z location=[lat, lng],
. l. g! I0 @0 U3 ^3 f$ \" q: d! l icon=None,
; L" g8 l; `* `
popup=label,
; Z9 r1 h# S; I5 |2 W
).add_to(incidents)
/ ?; w/ x" s) B; g6 c7 z% S
0 w2 o7 [8 Q8 k. U. r! \3 B% l2 w # add incidents to map
( D) D) j9 W& F8 F$ Y$ W san_map.add_child(incidents)
! u8 m3 q% |9 H) @; h
- q. W1 d r" O+ i$ A 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
3 F. n+ s' `6 [0 X/ J# U& m; Q import json
8 O4 |3 T: F9 M6 S H import requests- w4 ^( Q3 M3 Y' `8 k
H" d, y4 v2 H$ O
url = https://cocl.us/sanfran_geojson
, ?0 b9 U; G- [. Y- j san_geo = f{url}
9 E1 Z6 t6 U3 j; ?$ Z+ w' Z6 S san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
/ G, @4 V0 \3 T n+ V2 O folium.GeoJson(
4 E% i% y4 S3 M& P5 T. K) W, t1 X san_geo,
) R, {# S! Q# j+ d8 m style_function=lambda feature: {
& A* Y n* |' y u, t fillColor: #ffff00,4 M( @. `8 K" p: m. H4 L+ @
color: black,
* U7 D4 G& ~3 W ^4 ~ weight: 2,
5 Y+ J" _1 ?# r/ C I dashArray: 5, 5+ r$ N: z1 h5 P9 a- D$ e
}
" p3 L+ Y! }% S5 q4 p' L ).add_to(san_map)
* |: w# w( b! l# t: O& {6 J; Q5 a/ U
) U$ r4 _# N9 T #display map
- D) {; `* @8 c$ | san_map
) {1 ]: q, \. r7 A) @% l2 D5 D
; C; b0 j. g, k0 J8 e! r3 a
8. 统计每个区域的犯罪事件数目
: j# Y. T( A% x; P3 e( @9 |, e
# Count crime numbers in each
neighborhood" q N5 r" b0 n. x: c r
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
' v4 f+ M" d8 ~- L" L4 v5 _0 ?( `2 \8 m$ j disdata.reset_index(inplace=True)
) Q6 f! c, u% }! A" z disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
h3 H0 S; q0 ?4 V3 Q" L disdata
$ i; ?/ @2 q& U8 c$ `( i3 t
# T0 d& \6 D9 L9 x0 P 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
4 F* B8 j# t, L- d
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
9 u! n) o% |7 G( p
folium.Choropleth(
6 v6 b3 Y/ v, u0 b geo_data=san_geo,
! l" p1 f! q. L# h ]) c
data=disdata,
( P: b( w3 Y9 u7 ?5 O7 B columns=[Neighborhood,Count],
* U2 ^' X+ q- |- N% ^ key_on=feature.properties.DISTRICT,
4 g# c3 t1 o6 H$ b #fill_color=red,
' j4 i% M* q* u. F+ W# A/ ^ fill_color=YlOrRd,
, m2 z4 m$ r3 w! ^ fill_opacity=0.7,
+ L) [8 y; [2 p2 J7 w# K2 ? line_opacity=0.2,
. l, Q$ r+ B" w. R# t highlight=True,
0 h% x% _. e E7 y
legend_name=Crime Counts in San Francisco
0 H! P7 y9 P- {! A
).add_to(m)
/ e5 b1 U: x) d; M# K+ d m
# I+ ?& \& l- E* M* ^ ' ~/ J4 f f! k! J" f; p' F
n9 @( s. _( c0 x4 ^ 10. 创建热力图
; \& ~: H' L) l4 P5 U/ H
from folium.plugins import HeatMap
5 Z9 f& }' O7 U/ n+ `1 b1 _; Z4 S+ H O" g1 v
# lets start again with a clean copy of the map of San Francisco
1 }3 u; k8 q/ F% m+ N7 J' W san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)6 J" Y% H. |" A% ~/ q" K7 P0 z
* F# S- _$ d3 r4 u* D # Convert data format0 @' `6 C- T. c
heatdata = data[[Y,X]].values.tolist()# B% A6 y4 R2 i
, q; a) q# ]! t # add incidents to map
6 V7 K3 p# n0 l5 x HeatMap(heatdata).add_to(san_map)
/ Y0 P e7 d7 d
: `9 E, w) F2 {; [ san_map
8 @1 ~' u$ U- p1 i+ n7 v
: E0 o" u( u: [: l; a 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
- ^* m- P" c/ Q" U$ Q3 E" Y
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
$ M( p7 l4 U8 `/ T+ k, X, d) j
0 d# ]1 d( j7 \% f- `, D& I p 我的其他回答:
* s. p' @% P9 A: m2 y0 ]( \1 ~% e
9 O4 _ L" p$ }$ | ' @! p1 U \/ _7 V w* J
! X0 S" H% O/ @ 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
% k9 O- F) c. b- A/ s& Y4 K 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
; q4 c( n/ t& \7 W
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
) V" \" z3 s$ U4 e/ A
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
% |0 e$ k9 ~ P3 v' x
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
! }7 t+ w% ^0 q* G8 B% _5 _