2 ~7 j. U/ d9 Y# g6 \ E* h
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
' w4 H0 I+ S* I $ ~! |5 T- K/ M! T, L; ]4 y
使用方法很简单,操作如下:
导入包,创建一副世界地图" Y% U9 a+ E4 J/ u9 W0 c. f% @
import folium
4 h- c8 v, ^. k0 ^+ X import pandas as pd) `! \! H* R4 D$ X+ W
6 I; x* u }9 l: R, Q+ k
# define the world map
0 @# ~* X8 y4 l9 V* v* {$ k3 X world_map = folium.Map()
4 p+ b* H# U5 z. c# Q& {6 }+ K& C& U$ X+ ?# [: T/ e4 Z7 I0 H) y
# display world map1 d; M* e; X3 k0 c
world_map
& T3 ]1 l: K& I6 H9 D+ i
4 [* t; s" m! n3 v 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
: P0 ^" C+ }- ]: Q0 O/ P# V6 | # San Francisco latitude and longitude values
( F! r# c8 t( E+ Y latitude = 37.77
7 q3 n# e1 b$ P9 ]) u9 h, Y+ W7 M* X longitude = -122.42
% [: ^4 O* ?% s# R7 h
( F+ U0 v2 f# Q, g5 ? # Create map and display it
3 H9 Z+ `6 B: v' L* e( S4 z san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
9 l0 M0 y( k( L: @
# E4 `$ K4 U0 \' w9 ^ # Display the map of San Francisco# u V; W- q' x, | |' c; Q8 R! h
san_map
9 {# R' U" f( U2 {: e! Z
# r( F- Z/ t& s8 R, s
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
8 G% e5 ~, q4 \3 K # Create map and display it
$ p7 a2 h& J' A1 v* {$ _7 y san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
) D2 k4 ]. I3 u ~, N7 p2 s
! P L6 p2 t0 ?, k7 s9 A( J 3. 读取数据集(旧金山犯罪数据集)
) i" t, g: X! r; d # Read Dataset+ d9 V) d9 ?) }' Z1 X9 V1 Y: {
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
* O% r3 |& N* e0 I$ q cdata.head()
- S' ^* F& W# s: y/ X: W& E
2 H7 _% B% _& F 4. 在地图上显示前200条犯罪数据
! n( W0 J$ a7 s7 u9 z- D( u # get the first 200 crimes in the cdata
. m% D% d- T8 l; @/ c" m# v limit = 200
% m! T8 }+ V) y& H+ Y8 m6 @8 d/ Z
data = cdata.
iloc[0:limit, :]
2 T( K0 X3 V A( [* i
$ |. N5 K! g* j4 F. ?' x T# C; { # Instantiate a feature group for the incidents in the dataframe
6 l, O& A* B4 l+ A/ G
incidents = folium.map.FeatureGroup()
5 S# Z- G' e1 X! Z3 J
; Q6 v3 \/ C! M1 M
# Loop through the 200 crimes and add each to the incidents feature group
% L8 W) r: L3 Z for lat, lng, in zip(cdata.Y, data.X):
/ [! c8 _' |% n' r& z, E# d* S
incidents.add_child(
F. C e8 O9 r' K; S ?
folium.CircleMarker(
& ]; P' x8 z9 j3 e [lat, lng],
5 [1 z) ]) k$ M) @7 w( y
radius=7, # define how big you want the circle markers to be
" t) D; ^# h3 i# L0 ?6 Y( H/ ^
color=yellow,
& O) o; N3 y' |9 r) e( X fill=True,
- O8 g. h! L f# N
fill_color=red,
8 G& l0 F* Z- t+ E' `0 v
fill_opacity=0.4
, J6 A2 H* v; R2 M) T$ |7 c( j )
* y- b7 m a) ?$ x) O )
' f9 }& W5 Y7 K- f" ]
- I: _& p0 T* h Y$ }, U # Add incidents to map
$ M" ]2 ^1 ~4 j san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
6 _3 L/ U V+ A' c: u' P san_
map.add_child(incidents)
% w- _2 U; F5 j. Z
3 V& F, d+ X& J, s# y 5. 添加地理标签
3 w6 U8 }/ P6 _5 [. R
# add pop-up text to each marker on the map
# Q/ s: P9 d2 t; v1 L |* T latitudes = list(data.Y)
; r( T2 Q) x+ y/ h4 W* ^
longitudes = list(data.X)
3 l( R& q+ R- w; |1 N( W labels = list(data.Category)
4 h8 q# j, Y% H( l' Z- A/ F" b/ H3 ]
for lat, lng, label in zip(latitudes, longitudes, labels):
- b4 Q, z. r& m& _& ^
folium.Marker([lat, lng], popup=label).add_to(
san_map)
" e: G$ l1 |2 N7 F
" g2 U; W1 U* E; D e/ X! d # add incidents to map
# n2 H& o' A1 |, f san_map.add_child(incidents)
% u& L5 b; [6 v9 Q$ n6 D
9 ^! c+ D# A: o
6. 统计区域犯罪总数
' C5 ?2 Y4 g8 t5 ~$ E
from folium import plugins
( J. B* e# f8 ^& R8 B
2 S" l& ?# N: M2 X% k
# lets start again with a clean copy of the map of San Francisco
9 M' U* F' F$ T4 a) L- c! h3 c- |1 e2 { san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
' ^6 e e x! a2 z9 e/ ? {- s8 l8 j, k
# instantiate a mark cluster object for the incidents in the dataframe
# u* E. n: R' a, \, d. k& s8 ] incidents = plugins.MarkerCluster().add_to(san_map)
! R3 q# v% V& D% T" A1 S
& W8 R4 g/ ~7 i" d9 s' j # loop through the
dataframe and add each data point to the mark cluster
D& h3 k6 L4 e" e5 r( R2 G
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
, F9 ^4 c+ I" a/ z8 g- o folium.Marker(
2 B. x9 \' Y' m1 C: |# E location=[lat, lng],
# o* K& C. i( `# Y/ C4 V
icon=None,
; O, m$ V( U$ i
popup=label,
# I; X0 |; G' Y& G. Z" r# A( B
).add_to(incidents)
: X W1 l& F0 M: g; Y
# F/ f" N/ }% h9 X # add incidents to map
( G* H2 g1 B0 k; C0 L san_map.add_child(incidents)
6 B! X0 J" s* k8 _
7 d- l2 E* s% t) e. z 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
" R/ s. p' F1 w
import json
9 v4 Q6 \9 p- u) j A6 `6 A import requests
}* E! @; K/ O7 Q. j
$ j) F- V ?/ M. g url = https://cocl.us/sanfran_geojson5 S* p( ?+ R3 s" @) v/ U% c0 X
san_geo = f{url}
7 {4 L8 Q ?* }! ?4 V" Z6 ? san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
; q0 _, A1 G' j4 z3 x/ h" [0 Y folium.GeoJson(& }5 \- P5 j- R$ |
san_geo,0 i' O2 `0 r1 M+ [
style_function=lambda feature: { m+ @. c0 M9 ^, G' b7 s
fillColor: #ffff00,
: H2 E% A, m+ g color: black,
- m d9 z. E7 S) r3 Y weight: 2,/ j. J( q, c- o/ o+ W5 ~. _: a0 B
dashArray: 5, 5
/ T4 C- Z8 h' i6 H* f* }( ` }
2 C+ M; L% ^4 e5 H% R ).add_to(san_map)
, B8 C3 O9 u- S; v* ^* @) ]) o' ^7 G( i5 V6 p X; E% Q4 ^6 d
#display map! ^7 N: s: |7 A; h5 z' M( h
san_map
+ Q6 ?' ]: l/ c' p! Q4 b+ e
% f1 O/ M9 l3 ?8 ~2 V0 r
8. 统计每个区域的犯罪事件数目
9 ]# |7 k, d/ U6 O% c4 \: U# U # Count crime numbers in each
neighborhood @* C' i ^# k
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
, w/ U* }6 H( ^ disdata.reset_index(inplace=True)
1 O, t+ I0 H( v8 G6 l. x" @, d2 V
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
1 O3 {1 U2 K! u7 ^! b7 C
disdata
, m" }" i1 J+ A+ H9 J* b
! p2 @1 A: o1 G% F% S! ? 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
2 N1 y0 W; F) M& V( P. `2 \) Q m = folium.Map(location=[37.77, -122.4], zoom_start=12)
T4 W Y' \4 Y# r/ e$ M9 ]" L folium.Choropleth(
K! u8 H, r4 @" ~: s geo_data=san_geo,
, F9 l+ k/ q' G5 h7 m
data=disdata,
; J* z$ s" M9 Q6 S! C8 X/ y
columns=[Neighborhood,Count],
: s9 _& u9 H9 D0 L key_on=feature.properties.DISTRICT,
, g r+ t4 c+ q; v
#fill_color=red,
: g9 y/ ~' U. I6 I# B- P fill_color=YlOrRd,
( d' q$ g; T9 K L fill_opacity=0.7,
! \- ~1 Q/ ~5 u4 H: ? line_opacity=0.2,
. W1 t9 X! H g- l highlight=True,
% d0 d/ o& A* B3 F, N legend_name=Crime Counts in San Francisco
0 S' ^. B; X- a. C7 b9 Z ).add_to(m)
J- R0 j5 Z* w ^$ |8 N m
3 ?* ~- J7 h. g
$ [6 I6 a, A5 Q6 ^7 ]' U* R
g. O* Z. M( T5 d2 O 10. 创建热力图
6 t) \) G: H# Q/ B& j from folium.plugins import HeatMap! w, v$ g3 T4 h0 t7 N( a2 B
* Q& L# b( U: h+ L8 e* r
# lets start again with a clean copy of the map of San Francisco" v9 S- R% L; O+ j) _( S+ J# U% {
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
5 P- n0 Y" G1 y2 A" P# L+ L. {0 v" j( c% d% O
# Convert data format U' m' q2 n7 k/ Y
heatdata = data[[Y,X]].values.tolist()1 K6 D/ ` K, j1 O+ W9 U
) {* w n; Z% q; _
# add incidents to map3 d: S: z3 B5 T/ b! Q. Y) j/ ]
HeatMap(heatdata).add_to(san_map)- \9 `7 O, A% H2 b4 c$ t) m+ w
9 ?* F5 b% U6 [' B3 x5 ` san_map
% ]6 K; r1 e' D8 t1 M
1 h* J- M2 Z: Q 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
5 q( W% \( T6 q& A
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
& D% f+ L2 p. Y( \. J2 g
8 O# h3 b$ O, \. O9 A 我的其他回答:
, Z/ G# K# q4 T! @
6 h# i2 l! i. R! z9 Z v9 n 0 @0 M0 i) N2 m" r$ ^, m
( u. W( H4 T- O2 s8 w5 T 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
: u9 \. d5 P# G+ U8 L3 V4 D
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
4 u& j( X6 `+ N: m! x" a1 f8 t N 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
+ p' W9 P; N6 g/ s5 I/ l
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
$ I( R% Y# A6 l1 @% j: J
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
( m; b8 H0 }7 X [+ T