3 ~1 I" A9 a. w5 @' y" U
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
- m: |/ M% a# f B! Z # T x* {" M# |6 r6 S- }
使用方法很简单,操作如下:
导入包,创建一副世界地图3 u3 L9 R" k, Q5 g% l
import folium
& m- m9 @ Y3 F( d- U import pandas as pd
( x7 ~2 b# C6 ^1 I5 ~/ C! ^* A+ i: k6 p
# define the world map
. i/ a5 F5 b- y# c% o world_map = folium.Map()
% V- W4 u; i) t# W6 e. `2 \5 k, k: F# M$ h$ w* i( l/ n/ ?2 x2 q9 g2 {; U
# display world map4 H+ k. Q1 i& f% F
world_map
: Z$ O+ E* \6 ^6 a. U$ W
3 r7 M1 \% ?+ a3 @ h; }3 y4 V 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
; R9 C7 N& m5 W4 h- j9 F
# San Francisco latitude and longitude values# k# O) P/ b& ~7 C: n( p3 K
latitude = 37.77$ u2 ^8 D% c& F+ E$ @6 n
longitude = -122.426 x# m1 t$ b1 b2 F4 r4 p# q
8 x- w ]" Y: b
# Create map and display it
- G( J% f6 r" H3 U. k& ^ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
! c6 E9 A: i' X/ l/ P$ e; S7 o- A9 w8 x% a. K* F; I) B+ k' t6 x3 q
# Display the map of San Francisco) k! U0 a, Z# a. g! T- H
san_map
% G0 H3 Y! E. {6 w( a ) R. v/ J5 r, e- t
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
/ A C6 {3 s3 c2 U8 l) G9 \ # Create map and display it) o* ]0 J* m8 L5 w/ h" l. [
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
! Y8 o# m' F& a! L
, f e! n: A5 D; G; K 3. 读取数据集(旧金山犯罪数据集)
7 p/ m! P& @9 Q2 Z. [ # Read Dataset
9 C- ?( N! Z7 j6 E cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
9 K, _2 m1 o- y" v cdata.head()
. e6 b- u; ^; X% V& ] % r G, E/ L) J' t: K. H
4. 在地图上显示前200条犯罪数据
/ S6 R2 s1 ]3 t6 C/ H. v# o # get the first 200 crimes in the cdata
* E' ~# [" @- M7 r+ D# J limit = 200
, ]0 T) d- t" q/ o* @ data = cdata.
iloc[0:limit, :]
8 O: n7 Z' q: t9 Z, D! X, [
+ I7 A& r5 O) R # Instantiate a feature group for the incidents in the dataframe
0 U9 \# Z# j) c6 d incidents = folium.map.FeatureGroup()
6 I H# b3 h! c
. t& A! _) r6 U3 ]& P # Loop through the 200 crimes and add each to the incidents feature group
3 j3 u& l, D: m1 ~& {+ q# ^
for lat, lng, in zip(cdata.Y, data.X):
; U$ {3 R$ P2 v) w1 ` incidents.add_child(
& x& n: U, N5 m
folium.CircleMarker(
: R# r$ D3 H( r! `, @
[lat, lng],
5 ^, ?+ x) \1 `8 X9 j8 G, D radius=7, # define how big you want the circle markers to be
+ W, t: k, W7 @4 s# b color=yellow,
5 k9 `1 }" Z7 m o0 L
fill=True,
' L( ^& {# ~- x) i8 |
fill_color=red,
. H% ^$ w$ B1 N( Z1 K
fill_opacity=0.4
- S& f% v+ q2 u* _3 M8 R )
6 i) F) ^, Q$ d9 ^1 E% X7 ~
)
- e! x$ p! s/ c \7 q& q8 u1 ~% a
9 ?$ k. b* d# K, @ J, w3 y
# Add incidents to map
0 W4 P3 b6 y+ O W
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
# h+ ~, e* N% k0 P san_
map.add_child(incidents)
4 F, _" \$ J7 s
: g8 J" ? h$ K- f 5. 添加地理标签
; H `3 v# c- V+ W8 l2 J _
# add pop-up text to each marker on the map
6 ~; O m# ?( }9 \) B6 j
latitudes = list(data.Y)
~5 D$ \5 |, v7 \7 W& w/ v longitudes = list(data.X)
5 _) Y' o9 [2 A7 H, D
labels = list(data.Category)
$ X6 `3 _: o P1 S" C2 h# d" M* \( Q
1 x$ h) L6 C0 K& ~9 Z2 D- j" d: H for lat, lng, label in zip(latitudes, longitudes, labels):
( E* ], z$ N% [+ x folium.Marker([lat, lng], popup=label).add_to(
san_map)
- k3 g U) A( F
- {2 K: v0 o }- E # add incidents to map
+ a" H |6 b; r, W san_map.add_child(incidents)
4 `( _( H0 v8 i4 K3 _
! b0 S: f7 l' E/ ^2 |3 n& m 6. 统计区域犯罪总数
8 V, m/ ]3 E9 t6 ], @. c& D; U from folium import plugins
! f$ p, v9 i/ O6 s/ G+ E
$ S1 J- Q# E4 @ # lets start again with a clean copy of the map of San Francisco
7 A7 n4 V0 k$ ~4 o# z3 R/ r! d5 B
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
% y$ l* Y9 D9 _: s7 m% H n) L6 ^
, x# j) \3 a* e/ P: A # instantiate a mark cluster object for the incidents in the dataframe
# f% }) M( f @' U* e+ X: V9 c incidents = plugins.MarkerCluster().add_to(san_map)
. O; R4 ~. }3 N( W; [6 g4 x
; Y4 G' G7 J. y4 n. H ^ # loop through the
dataframe and add each data point to the mark cluster
5 E. a) |5 a$ N/ \# t0 q5 ^& W for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
& P: Z2 S$ V$ o9 w folium.Marker(
2 y% n8 k- {+ q, e6 \ location=[lat, lng],
8 v: ^( p4 y g6 A icon=None,
/ n& |( O7 V& v3 I: p0 `
popup=label,
# F! p2 X' D! v3 J* Z ).add_to(incidents)
' P7 x& q0 q) t4 y) F/ t1 V ^1 X
T K; }$ L8 a' h
# add incidents to map
! G0 t2 _2 s) h y$ b5 d4 X; w6 D% G. y san_map.add_child(incidents)
V( d q1 r5 y/ F9 d% b* ]$ {
* O( e& a0 u: | X 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
- s1 |4 ?$ a6 W0 r8 O5 f0 x
import json
* D3 l8 U: W% A) N' d import requests
" k' N+ v( [/ @3 ^7 o
, k/ ]( ^; s7 G( V R+ F url = https://cocl.us/sanfran_geojson. f' D$ E' X8 R( c7 i+ C5 [/ Z
san_geo = f{url}1 p8 t9 ^% J8 Y+ Z$ M! K
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
: w% M, R7 C1 r: ^8 _; r' g# P) e2 R folium.GeoJson(
3 _6 u4 k% g. ^. B/ N, x san_geo,
3 O. v- c6 G3 q5 w' E K% s# h style_function=lambda feature: {" ^1 Z0 U& e; V5 B# [ n/ s5 U
fillColor: #ffff00,9 P( j& x9 `! p; R1 L, C3 {
color: black,
% i8 z& B) f( I weight: 2,
P- W8 F( R0 ^" p9 I) } dashArray: 5, 5
( p# `% L' x5 h: }3 ]+ u" T }
S: q0 t7 @: U# i3 I0 {, d F ).add_to(san_map), C8 Q! m6 }5 l0 J- a
% G5 K0 @8 e9 u/ f$ J
#display map
r( |! J1 {5 G% o/ z* Y san_map
+ R7 Y/ I' O. b1 `0 w& x( O/ |; I0 l
4 O) ~& z, L; n$ k0 x+ C: k 8. 统计每个区域的犯罪事件数目
3 [ b' ^) B0 d4 u) ?
# Count crime numbers in each
neighborhood9 ?7 p% [+ ~& u0 L% U9 a
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
, t" Q: k) H; D0 H) E/ g \ disdata.reset_index(inplace=True)
, u% e$ i4 ^1 [; D
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
/ k0 d% \4 r# k' q( z+ R1 @ disdata
, t- B0 h2 E0 m8 K' N
7 h9 K" ^( U+ M8 \ 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
& ]# O M, {8 T' k m = folium.Map(location=[37.77, -122.4], zoom_start=12)
5 o5 o5 _& g$ u. B! L2 J/ O
folium.Choropleth(
- q7 o' V! _ [& t# w* \' x" r
geo_data=san_geo,
) l' K/ S& h. j) ?" u) w1 x
data=disdata,
/ L; l) h) l+ \1 b2 K' ~, @& \" { columns=[Neighborhood,Count],
( R. R$ z% N; D. A! F7 R key_on=feature.properties.DISTRICT,
& _, x R8 a1 r& N- ~( ?1 {* k
#fill_color=red,
+ z( w% H6 s; u- N5 _: D
fill_color=YlOrRd,
: r- a! n8 }- L; e2 q6 J. p fill_opacity=0.7,
0 U e v- t* Q3 g1 |; _ l
line_opacity=0.2,
# V r% _' F: \6 t& v$ m, H
highlight=True,
+ M! I" n }1 D0 n7 w2 ^ legend_name=Crime Counts in San Francisco
6 e4 @( d x' i0 `1 i ).add_to(m)
* B: u# V7 `3 u7 s: P m
# T4 F/ E2 |2 v! W$ D0 x
+ e8 k3 c, S5 ?, b$ q: V0 K% z9 @
4 _5 i# L2 q: N 10. 创建热力图
. b( ^3 w1 R* P6 X. ?8 h" T& y from folium.plugins import HeatMap
+ i0 v% e W0 y8 D4 p7 O! I% F- N) ^
# lets start again with a clean copy of the map of San Francisco
/ d, `, `" D3 T/ O) }. P5 S san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
6 R; s) E) H; ~5 D5 m3 r' m4 c/ \
# Convert data format' n3 S! m) A5 c. V
heatdata = data[[Y,X]].values.tolist(): v3 t! \" O1 S$ c. L
4 `8 W n) n5 `6 a0 e) A6 T # add incidents to map
3 Y/ c! _4 X! Y0 U. e m1 P HeatMap(heatdata).add_to(san_map)0 {, M- p6 a6 Q9 A* S( n
; I" [9 y4 m* J6 l& Z5 I5 t, j
san_map
* {% c; y) v l" f) a% ? & j0 v7 Y1 o) {; g5 R6 b
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
) a) P$ ?) l/ k2 F: k/ a8 K 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
1 N( D# `, P, _) u* ]
! q) e2 j' b. W! g! }6 V9 C
我的其他回答:
6 n0 ~- X' k0 T3 W/ \% _
% k! l% M h1 r$ O
& W( {" X- w3 O' I
. Q. w. o% \# | E, p 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
6 Q# w) }! y7 v' o* j& \
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
3 }" b: ^9 I6 G- A" F
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
! I! Y% S* e: D2 B, a* |5 k" Z
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
2 Z! \* O/ B/ {# _! f( l/ [
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
O- S0 \. D1 N4 J `& ^