8 [- N2 o2 a( G
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
# m- Z) V. [* K+ P
3 ?9 t" b2 X. |4 f! X, p3 j
使用方法很简单,操作如下:
导入包,创建一副世界地图
; }/ a v& J- i: N5 P+ k |! ]' o import folium
# u/ [( R2 y( l8 U! F import pandas as pd
$ _* F/ L3 P- `; i" u* r' W% h* X5 a$ j& ~7 x8 ?4 Y; N
# define the world map
% y% B. C- L6 C+ Z world_map = folium.Map()
6 Q2 s8 d* _( Q4 z0 j7 Z& D+ i( W8 B' H( C9 F6 j7 `9 S
# display world map* G+ h' a- o- P8 z3 S" b
world_map
- Z3 X, L7 R( {; E; X7 e) ?, z) D
9 W% c8 J! z1 {5 f7 C 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
( t- O1 ?3 K1 t! G! A. Q, ?+ K
# San Francisco latitude and longitude values8 u) _) T9 q) R( p& X) Z/ c2 N
latitude = 37.77+ O3 d- {. Z4 U2 a( l! j) |! N
longitude = -122.42" ~0 T0 u: _4 U5 `; S: u$ V
8 {' M2 }- K3 r, W/ d; a3 h
# Create map and display it
6 N" b6 I% [& O# p: u7 D. Q san_map = folium.Map(location=[latitude, longitude], zoom_start=12), o6 e7 i! e+ M( e
0 D! O- E. [+ j # Display the map of San Francisco( R! p0 g: x1 _( E. |# j8 L
san_map
. j+ u8 M4 C: I4 _8 }1 }
& N3 \- g. o4 U0 V3 Y3 o
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
; w. e" t1 z1 Y# o8 E
# Create map and display it
" a. L8 j4 l2 J/ I/ a" x2 @' U san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
: V3 \& K8 X( T F* Z2 w, z " I1 m P. A) I* A! n9 W
3. 读取数据集(旧金山犯罪数据集)
' \9 D5 A" \) }' t6 }3 b3 D6 r' x # Read Dataset
$ H0 ?" c' T. W cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)7 A( ` h% G/ U5 K/ J% C
cdata.head()
+ b3 s: Q! o c5 T9 O, w
* d6 g6 n7 ]6 T% I 4. 在地图上显示前200条犯罪数据
) u7 N$ F, T/ @/ b2 } f
# get the first 200 crimes in the cdata
# g# H( T! i2 C' N% Q: z" ?
limit = 200
1 x3 f; v, k, O7 R! W& } data = cdata.
iloc[0:limit, :]
% W2 L. o* l& m0 q6 Q+ ~0 G; ^6 H" C
% p I2 [8 j5 _
# Instantiate a feature group for the incidents in the dataframe
9 b/ i5 v2 }) ^$ T+ i% _8 t
incidents = folium.map.FeatureGroup()
1 {3 U% }( x$ G, j
- H4 u/ O3 e. j) ~- j0 | # Loop through the 200 crimes and add each to the incidents feature group
1 T9 X1 ~( Z" R/ E. l for lat, lng, in zip(cdata.Y, data.X):
: S1 y3 W* V6 M$ E0 R
incidents.add_child(
4 U H; C/ k. |* b' z
folium.CircleMarker(
" ]1 G: p- s: s1 X9 B9 o" ] [lat, lng],
' x. d2 ?$ E% F' }& b4 @
radius=7, # define how big you want the circle markers to be
; w$ `/ V6 ^9 k' z, O7 \
color=yellow,
8 M! i5 p& x7 t9 G) e/ C fill=True,
/ i+ j3 A. f: V2 j, ]. j1 h
fill_color=red,
/ D* Q! `8 X7 m1 v W: D; { fill_opacity=0.4
' T6 n& E! E7 y7 ^- ~
)
% D; \/ r) \& L' |
)
" V1 y q! o( e1 y5 z- i* q3 v6 K' `' n
. i; q1 u% C L5 x, R* [8 y # Add incidents to map
4 q& b! J6 v/ X, v* X
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
2 N8 I# v* @5 v san_
map.add_child(incidents)
6 |3 h% t( R7 } w+ v) h
- Q+ a& v! a: J$ @$ y, N" @! W. r5 N
5. 添加地理标签
4 I* g/ r* i, t. P$ G9 ~ # add pop-up text to each marker on the map
, n% M# J$ e' d. c8 w
latitudes = list(data.Y)
x8 F1 ^. l! |( i$ G5 a! D
longitudes = list(data.X)
1 A2 Q* O2 t Q- w8 k
labels = list(data.Category)
+ G! C" o1 S2 V3 x1 J1 i
7 d7 i: T) E8 T9 x: Z for lat, lng, label in zip(latitudes, longitudes, labels):
, D- T( J/ D% A: Z& O; k, X
folium.Marker([lat, lng], popup=label).add_to(
san_map)
8 K' G' _0 A2 ~* _1 [2 z) S' }+ |
# add incidents to map
; J {/ l6 y+ H: _, q san_map.add_child(incidents)
" L; r1 f/ B/ `4 B$ T6 }
8 I) Y, R3 {5 t; A: ~0 O
6. 统计区域犯罪总数
1 }7 q! r: _; S" |7 p) C$ K$ \: F: a from folium import plugins
) E3 M* ~; K9 I0 V- j, E' m/ m) P# I8 F
# lets start again with a clean copy of the map of San Francisco
1 T$ G6 t: r/ z% R% H' v4 R san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
3 Y2 z8 u! a6 G0 M
4 t5 ^6 c/ q5 _6 A
# instantiate a mark cluster object for the incidents in the dataframe
: G4 n- Z" x! J7 H5 G8 G incidents = plugins.MarkerCluster().add_to(san_map)
. ^* }7 Y) k# H; ~4 h7 ~/ C3 ?& [
5 m0 O9 I3 l/ @) e6 C # loop through the
dataframe and add each data point to the mark cluster
* f; P* c4 ?. r4 E
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
Y6 e$ D/ v7 S9 [
folium.Marker(
- d% E v9 o, [2 U H
location=[lat, lng],
, x$ t( G0 B, j* O6 E
icon=None,
7 c" ~1 {) f; ~5 t popup=label,
1 s& d1 r% \3 o/ y; x ).add_to(incidents)
1 n3 z; i% j" t! c. C& w
* w+ F+ d$ U& B `! x1 @
# add incidents to map
/ e* @) S3 {- ?* ?& l" Y* q san_map.add_child(incidents)
+ r, C( Z+ o+ `% B7 S, O8 G/ ?/ B
4 o* z0 \, l$ J! P# B 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
& K8 m( p9 i: l. h8 s T
import json
) s {% J) o6 J, \0 F9 z import requests& i' D: a9 ^2 _' S" ^1 ~- n2 Q
+ P( Z% o" g& W url = https://cocl.us/sanfran_geojson9 v0 u) o" q: v& ~! D( e
san_geo = f{url}( A# j) ^# ~; c& R) K+ x
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
. H" Y6 K! ?+ {! W5 l# r folium.GeoJson(: J, @- @# m2 d, w1 E t
san_geo,7 X7 E$ D3 T" e
style_function=lambda feature: {
2 ?9 F# R' J0 v fillColor: #ffff00,
8 l- K, \( j2 P/ h4 z0 u$ a% t' F color: black,
) t5 q9 j# P B4 l h1 l1 p, M% [# V weight: 2,
7 h. B+ O7 |" U0 | dashArray: 5, 5 t. M0 T/ a* E4 u
}: V7 _( O, O% {
).add_to(san_map)
4 b5 [5 d! H( G! K/ Z# Z# s) D& t- @4 g* `3 x
#display map
/ k: V" W- `& u7 g# Q2 n san_map
$ K* C$ \4 h3 v8 p" \
" g( v/ L8 [3 }7 j1 ?8 a
8. 统计每个区域的犯罪事件数目
2 s7 Y/ y; b% u& l) Y7 k # Count crime numbers in each
neighborhood
+ k" o6 ~, P0 f- E; O" H disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
8 Z! D* m. t. l" T7 l, P) x" V1 P disdata.reset_index(inplace=True)
4 q+ v9 y* [ K8 V4 G( f
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
Z; [% Y" V8 D) a/ Z disdata
+ Z: O H$ ?6 G j5 K 9 I) t) Y2 T4 X2 [; d
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
4 x- q- j% h; |- U3 m& ^+ w
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
1 g) I9 O; _' ?3 C1 Q4 V3 f R folium.Choropleth(
3 `% S2 f! l& {5 e/ s" n5 [/ L geo_data=san_geo,
" V) _& F( d' d
data=disdata,
R* U% O0 O7 `% j- }# a' l3 { columns=[Neighborhood,Count],
9 \( h0 y4 n# R s
key_on=feature.properties.DISTRICT,
3 k% ] I1 s7 K+ H" a: E( S% x6 \ #fill_color=red,
( [0 a4 U. f% _' l
fill_color=YlOrRd,
( A. D b: J: I. r7 l
fill_opacity=0.7,
6 l ]* }+ r/ m
line_opacity=0.2,
6 ^ _; y! V% q: o0 `$ P* W4 ^& `
highlight=True,
) [$ E! y; M+ b- M1 P
legend_name=Crime Counts in San Francisco
9 ?# R, J/ W& ?' H; V& \9 n5 O2 v ).add_to(m)
3 q5 F( z+ ? M4 A+ W5 f* z m
" i' Y- d4 i* ?- q* v8 D; G4 }
0 T2 }3 n/ V' i3 ~6 P. Q
# U1 V6 \/ ~7 L' q2 N" z. _ 10. 创建热力图
/ c$ d. |: J5 M& O
from folium.plugins import HeatMap
' w. {; {, r, }$ [" y$ Z4 J( {5 Q. f
# lets start again with a clean copy of the map of San Francisco
6 a+ L$ k1 a4 k4 V san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
. d& T/ C# C+ X Z: ?2 o, O- A1 K t& Q) K" |+ ~* ?
# Convert data format
/ E) |# n: s" T2 l- D1 N heatdata = data[[Y,X]].values.tolist()
6 P* G9 }7 Z8 A8 B% L3 Q, s% A2 R$ ?
# add incidents to map
5 L: Y4 t8 z; o. |0 q" r7 Z* L HeatMap(heatdata).add_to(san_map)
) A: u4 n6 t; R! T5 k j7 F, M: j: n' P6 Y1 G2 S! u7 ^1 {" g& @
san_map
) J1 n1 a) G& U7 v
$ G+ {4 `2 Z: c0 [$ ~& P 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
8 k* b/ M5 ~6 n0 |" i+ g9 t
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
! L8 X( c$ r* j- e
0 J4 S' S8 ~) l* @8 v" b* v9 Q
我的其他回答:
1 P6 N( h" w2 R# i" F1 U+ m& p
7 q) c ~: C8 o: a& m {6 u. @ , x. ^4 S5 g3 e* Y
* P$ p) D$ M0 [" x* `
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
; Y2 Z m0 b6 B 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
, h9 k! T. c. A' Y 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
' N T z. `6 i 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
, w' v# v7 F" N0 W. v- l( G1 ?0 L) B0 s
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
3 V6 w! L Q' b