: p% S; z. S A6 d: W" H. v( ^6 t 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
0 N, R- Y) f) m. c; g ! w, w+ y, j6 ]; D/ x
使用方法很简单,操作如下:
导入包,创建一副世界地图
! k/ ?' z1 L0 x- Y import folium
+ _$ C% c5 e. C, S import pandas as pd
: i( v6 p+ l4 a) R" V: \
5 F9 a3 I, e, a2 Q # define the world map; H4 T. w. [( T# O/ t* ?
world_map = folium.Map()
7 k* N& i) y3 m4 p
: c5 x6 b* a; G# ^) |0 G # display world map
! r# s. o! v) Q6 c$ p world_map
4 k$ m& k m3 b. H$ Y, j: Z! j. x# d: v
9 M' a* U# M6 a# S- x" Q 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
5 ^2 H. p* P0 {* ~, B) P" d) q: v
# San Francisco latitude and longitude values
. N3 h9 C8 P+ X# Y: L latitude = 37.77
0 O! V: |6 t0 R! ~) [1 b& ]$ g- H longitude = -122.42
0 O9 y. q0 ?9 k& I4 P5 y
! Y/ V4 H- x: x7 M8 \( w J* H # Create map and display it: U( @( ]6 B/ Q
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)/ g! _; V+ y) S" Y1 O# ?
0 \+ h, ]5 j8 Z- S # Display the map of San Francisco
7 O6 ?& C9 P& {3 P' I, o: Z san_map
9 `$ w' B5 W# C$ k4 u0 q7 I
" V7 \! Z+ s* P1 m; s. J) k 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
" z( O' g: ], m% P+ ~" j/ y
# Create map and display it& V; V) X* Q/ F( H/ s
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
( r5 {1 I& N4 J6 z! b' E
s; W6 o# u4 E/ V4 F6 [* C 3. 读取数据集(旧金山犯罪数据集)
& s ?3 O" y# K4 ~2 ~
# Read Dataset, W a6 l6 g1 M, p) n4 U M
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
1 ]# e- i- [5 P8 T cdata.head()
K# c j9 D" I# E
- l+ a) Q& }! u7 { 4. 在地图上显示前200条犯罪数据
8 f- f6 ]6 ^! d2 Q- d
# get the first 200 crimes in the cdata
; A! O* G" c# ?7 j4 H limit = 200
) T4 K8 \5 W/ A$ G/ @6 o5 | data = cdata.
iloc[0:limit, :]
" R" |. n' D6 q t
3 x+ |/ b6 m. ^4 Y) P
# Instantiate a feature group for the incidents in the dataframe
* C* ]$ R2 [" }) s5 X/ n
incidents = folium.map.FeatureGroup()
9 D! G5 G' M% p2 F6 F2 k" {' k
+ m# i, T$ Z' O # Loop through the 200 crimes and add each to the incidents feature group
* {3 `( l+ y5 i# v1 O: r# K for lat, lng, in zip(cdata.Y, data.X):
& a w. s" _$ L p
incidents.add_child(
% M$ {: \* v" ?: a folium.CircleMarker(
" S3 b$ z8 l. ?3 o3 P5 E) b- } [lat, lng],
. v4 x) k( D/ G7 D$ _. [
radius=7, # define how big you want the circle markers to be
* J. p1 B% [" n R: H1 {! W" b color=yellow,
; F( z/ b/ e3 ?% E S fill=True,
2 W) a7 }% w2 Z3 b
fill_color=red,
6 S( ]. o5 Q0 i3 P3 K, p/ l; T1 n
fill_opacity=0.4
9 d( q8 g* B8 ?$ _2 e
)
^; e% r6 v! U, b1 z4 K )
# [6 c! J9 W! t) |# W" b8 ^. K' S9 h1 Q( G0 F f/ I
# Add incidents to map
- x1 C f, s2 O5 N; q san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
4 q7 m5 X. p4 v san_
map.add_child(incidents)
& `- l! n& D& {* ?( i
+ C2 g* W! T& m
5. 添加地理标签
4 O6 w7 }( R7 \& b- h+ X& [ # add pop-up text to each marker on the map
2 n7 v8 w- i5 V9 T6 J+ |/ H N3 X latitudes = list(data.Y)
) g9 @* C3 X+ q7 j
longitudes = list(data.X)
9 p1 Q2 C$ k4 ^( g2 s3 N& Z" c2 n labels = list(data.Category)
% `! H3 Z2 f ]$ v0 V _7 ] H
& w5 c1 @! x; o* n for lat, lng, label in zip(latitudes, longitudes, labels):
, k- H9 H+ s& W/ A# a
folium.Marker([lat, lng], popup=label).add_to(
san_map)
+ g8 r; t1 J/ |8 R0 J& W4 G* ~" E
2 P9 G1 K# I. ] # add incidents to map
! J) M& S: p7 O4 u1 H san_map.add_child(incidents)
; `; b" @$ g3 l( w 6 E. M( k8 y1 U1 x5 ?
6. 统计区域犯罪总数
3 h' I* v* [ T# ~+ g1 f- I
from folium import plugins
9 c- M; M9 h/ O& f4 n' w! R4 O
4 b' P" _9 y( B; S # lets start again with a clean copy of the map of San Francisco
" k& u5 j' b/ \; b8 O0 l san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
; T$ d! t& O! L
7 G5 ?8 `# y2 J0 j% e! c8 f. `/ `
# instantiate a mark cluster object for the incidents in the dataframe
0 |' r q o0 N: K0 C3 k1 h, n
incidents = plugins.MarkerCluster().add_to(san_map)
V% P m0 ~2 D8 ]
: _+ B/ G* F- j2 B5 \# J+ o# i # loop through the
dataframe and add each data point to the mark cluster
; r7 ~1 s! D. B! y& i+ l% L for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
, V' L$ m" w% q' T y1 H9 @
folium.Marker(
1 O' T+ S9 y% Q b+ ~
location=[lat, lng],
/ \4 i% S. k2 T
icon=None,
3 ^( x- [ U C% @5 @
popup=label,
' K0 d; v2 ]% z
).add_to(incidents)
) ?4 T, W0 u* c3 J/ p7 N- d6 ~- g6 x
# add incidents to map
b' N5 e" P `4 [ s san_map.add_child(incidents)
6 Z: f8 A# X+ D& {5 L& Y* B a5 L( |+ m) P
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
* ?& G0 f7 ]* D. B% k d! P- U import json
; O- u8 J8 \) j, M import requests; }) b: I% k2 V# c# Q
1 Y- m% f2 p- {! k1 ?3 }
url = https://cocl.us/sanfran_geojson
$ K1 o: g3 ?# Y# r N san_geo = f{url}
8 ~3 X4 _0 W1 b$ D8 a$ Z san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)2 P' i6 M* B/ A$ u
folium.GeoJson(* S/ o9 [1 J1 Z4 |9 B& p
san_geo,
6 B: b. c4 g& | style_function=lambda feature: {
7 ]6 }7 O) a7 D% ]8 h fillColor: #ffff00,0 D* T0 \3 _4 X. b5 y0 v9 I
color: black,
q7 }- K6 e8 t& s weight: 2,; x' z$ K$ z0 {2 ]8 g7 @
dashArray: 5, 5+ b1 s$ ?; c# O/ {" W
}/ @* Z3 b6 ?2 @! p6 I' ]
).add_to(san_map). I q7 U2 f5 g1 h3 g
# k! ~/ K3 L8 r4 f #display map' _3 f% o' B. e0 n( M8 u W/ F
san_map
6 B) V: x" k7 y K
* X3 c: K/ c; N7 b! G 8. 统计每个区域的犯罪事件数目
5 e( `2 V& Z! B' D- L # Count crime numbers in each
neighborhood
1 \* n# a8 q# L' i5 g- H- r disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
5 ?. {& v! W; I3 W1 ? disdata.reset_index(inplace=True)
( c5 ?# l1 b @ disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
d! B# W- A }$ l disdata
9 x: J0 @& A7 G2 C& {) d5 G/ g& P3 E
9 Y2 h5 N$ g) x" c" G/ h
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
+ a( a' e9 i6 ` m = folium.Map(location=[37.77, -122.4], zoom_start=12)
5 s" z4 w Z9 U1 f
folium.Choropleth(
) F6 D3 S V4 z, f5 j
geo_data=san_geo,
4 E5 R0 N- _7 b. k: i2 v data=disdata,
* K. B( m* B! D3 h/ [
columns=[Neighborhood,Count],
& B% v+ }* v( P" M key_on=feature.properties.DISTRICT,
9 b/ Z5 y, ]! E/ Q4 ?" ?$ i
#fill_color=red,
" n. _6 n0 U! w4 m0 Z fill_color=YlOrRd,
1 q$ [1 a7 f+ \# x3 S* O8 L/ T1 d fill_opacity=0.7,
& M, Q) m& n$ \4 ?- l line_opacity=0.2,
9 y, P( y# h6 T5 x
highlight=True,
. s: H5 A# x, K" ^/ T( x! x. }! B
legend_name=Crime Counts in San Francisco
8 E) j5 @- ]3 n @& _% Q. h& q ).add_to(m)
0 @4 m6 Q- R0 |7 `, L( N& P m
) t5 y+ U! h5 U( w, y
0 k4 Q' M/ U7 x! K' M- Z1 [
0 C8 x$ L5 S' H( n
10. 创建热力图
- I" t s! p3 y4 a9 o& F; E9 E
from folium.plugins import HeatMap
7 ~ J4 F% P, ?$ e+ g' ~, E
3 L7 k; d8 S' @- M: @ # lets start again with a clean copy of the map of San Francisco
8 o: L" ~& B9 m- l san_map = folium.Map(location = [latitude, longitude], zoom_start = 12), t( A8 o" r$ H. w$ g, X( N+ N3 L
4 I' G* O1 m# K& K& J3 d
# Convert data format
6 X# P6 M; f/ H3 \& }4 h4 I6 R heatdata = data[[Y,X]].values.tolist()
% B, f9 O) `1 N8 d; y# Q d) Y9 D$ f; z( U9 S
# add incidents to map3 B2 L: H0 {6 X) I X, q
HeatMap(heatdata).add_to(san_map)8 y9 f3 }% ]& N1 b/ k" Q
0 E& G- P3 W% q! E3 v san_map
9 V% ~( r- e X P 0 g! o) d5 p% D% _' ~% k) b' ?
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
6 v1 ^/ v8 i% y H; s0 P
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
- _; _* ^ r8 Y6 C P( I 0 `/ q. ?6 H* Q C- z' e
我的其他回答:
: F9 ^: c( J6 _, K+ r2 o3 c$ D- g 3 |, j% c$ d$ ]( h6 S
! M, }+ p+ l$ o" R: q7 z% ], i
- J. B* y0 g# k9 r m K7 G 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
+ k4 z2 G% T" G7 d9 [7 `4 A
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
6 W; |! N9 g2 U+ x+ m( I; L0 H
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
" k) n! i1 J# V8 g
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
8 x1 ]% B% f6 h1 W: m
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
4 w% ^) `- C- X9 g- u& G9 o