9 p7 t9 C. v" ^. ?" k
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
- U8 _% V8 m( t% d # D( J6 A1 f( X8 i
使用方法很简单,操作如下:
导入包,创建一副世界地图% p+ j) \5 {6 z; |, i9 ]% ~
import folium2 `4 s5 {6 E. A& m* C, [% I
import pandas as pd
& K( [$ \: \) b6 J6 T$ R% S
% g' t: _" M1 c: O% s # define the world map2 r6 \9 T8 V- R$ K0 L) H( o" H7 ?
world_map = folium.Map()
' s$ d, e! r% V9 Y m w6 }+ P; D2 y+ Q) L& ]' l* ]
# display world map
% k8 j& R! k0 J- L world_map
3 O. S. a4 {$ x! t* b0 z2 z4 P
8 b, c0 N2 G1 s& d# E 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
9 w" `3 ?$ T+ Z$ J0 n # San Francisco latitude and longitude values: t6 a0 w# k% v: T% Q) s
latitude = 37.77
1 L4 j. k2 \( W% k) X longitude = -122.420 w4 f0 c( I! N& @
) T! t) x% p2 c3 F1 j4 u
# Create map and display it5 X4 x* {% W5 N
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
" b+ d3 j c& r* \
- S+ W. j- s$ V! f( b' v # Display the map of San Francisco
3 H, }! S8 l- o: H san_map
0 k$ i( q, L& v0 t
! p5 Y+ {8 r+ P- T 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
[0 ^/ ]# b% a4 Y% `) d
# Create map and display it$ m; I# f8 X. D: d8 g
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
U1 w; D& J+ M9 F2 k, Z/ o
4 \, A3 E/ X! Z% f2 a& W 3. 读取数据集(旧金山犯罪数据集)
- M6 T2 F, a# ?4 E2 h/ o # Read Dataset
7 N8 Y( [: o0 n$ [# e0 q. F cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset) E. H$ I0 j9 v8 p
cdata.head()
# `3 j! w S8 j% O 1 T' \1 S( T w. P5 }8 P
4. 在地图上显示前200条犯罪数据
# W$ P; _+ q e # get the first 200 crimes in the cdata
$ _* f0 _' u7 B/ @4 z( K. r
limit = 200
$ Q& _' J' [1 f- |0 ?) E6 l data = cdata.
iloc[0:limit, :]
* J- W* L' B3 s! @. j
0 y/ L( t0 v5 p& x. c # Instantiate a feature group for the incidents in the dataframe
; I- h W( e3 W6 T* R* O8 K1 y- W incidents = folium.map.FeatureGroup()
9 p) f) Q6 k1 V% W0 Z2 B$ g
) l# B6 |4 J2 n3 _% I7 }4 { # Loop through the 200 crimes and add each to the incidents feature group
$ n; D9 ~0 ^$ r, F for lat, lng, in zip(cdata.Y, data.X):
1 }" B( {. [0 D3 t incidents.add_child(
& t7 k$ u( k2 { o6 ? folium.CircleMarker(
; n) y* m& {. t- @' Y' E' m0 B
[lat, lng],
1 b+ N# V9 i$ J3 O
radius=7, # define how big you want the circle markers to be
0 L4 g9 V6 x7 h( g1 ? color=yellow,
; H4 t1 |6 f; |1 h0 g1 j fill=True,
% K; B3 ~1 p% I+ a; \# n fill_color=red,
7 Z5 H/ D. E7 u0 {4 H fill_opacity=0.4
0 A7 t! }2 E5 f2 E, }# d6 y )
# N" u% u3 X5 `, B
)
6 ]% x+ T# g' [3 Q; T' q
% j0 v6 B5 u+ M# W( h
# Add incidents to map
( o5 e3 m+ r+ ?, ?+ i* @
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
: ^- C8 V2 a, S- S
san_
map.add_child(incidents)
* g1 M4 I0 F; d# Y
4 K+ [1 m l+ ` 5. 添加地理标签
- a8 K& I/ x3 {9 o: l9 p # add pop-up text to each marker on the map
$ P* O* j% G N" l8 J- f latitudes = list(data.Y)
4 {- \' t8 \9 }- D longitudes = list(data.X)
+ ~+ G/ A! O, M% J$ Z
labels = list(data.Category)
& g1 |6 ]: @7 P8 Q
) ?. V V/ q! H B9 A
for lat, lng, label in zip(latitudes, longitudes, labels):
! a1 f+ f+ J ]( Q4 \ folium.Marker([lat, lng], popup=label).add_to(
san_map)
' ^3 G! y1 N" L$ c+ M$ w! W" d7 p
- e/ N! S2 g+ r% c- l9 T8 Y3 G( N # add incidents to map
- |, Y0 H2 c; {; i* {" o san_map.add_child(incidents)
# z- {1 Z: u8 r' a; g
6 g; U0 G2 E& Y# Q5 I, S3 U
6. 统计区域犯罪总数
* P- I$ ]7 `/ M
from folium import plugins
1 g5 D9 y& u; i1 m% b- Z
; }7 K, ~8 \% j # lets start again with a clean copy of the map of San Francisco
' Z2 O& [, e: ]3 `: l7 `
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
1 f& J# U" b0 v D
5 ?3 a( `6 k! b3 W* u- q- K g
# instantiate a mark cluster object for the incidents in the dataframe
3 t% |3 n: l+ `4 r incidents = plugins.MarkerCluster().add_to(san_map)
& M {$ m- R/ i+ ]) s) E
' m, |$ y/ o+ Q+ f. D # loop through the
dataframe and add each data point to the mark cluster
5 O6 A; j2 K6 O/ X4 l# g
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
+ ]9 r& I3 h( f
folium.Marker(
1 f$ g2 h* ^. ? location=[lat, lng],
5 I5 m* V Q9 K
icon=None,
7 ^6 p* O5 j5 u popup=label,
# J- M1 v# v7 J1 d0 w9 R5 m ).add_to(incidents)
* Z9 E( o. z, p J
0 R9 [/ H5 q$ E( z7 v3 q4 t
# add incidents to map
& Y0 V% A7 r% U% J: N w" u; O san_map.add_child(incidents)
! ^( ]9 |" f+ k) T
/ u' \" u, N) ]- Z2 T# `
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
$ x- \" h4 |* a6 B9 ?, i
import json, E- @7 F g* i# L$ K% H
import requests; J% D( Z5 z4 A& h9 n1 T; }
. P# H6 x, N- f6 `5 x- B
url = https://cocl.us/sanfran_geojson0 k* [& T. }( ^4 o [; o. P3 T
san_geo = f{url}
! a" o! v% t# ~0 x4 ^2 B san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
$ J- V8 _1 l1 |( W- F folium.GeoJson(
2 I4 T; B J, G, }- ?# Y( a san_geo,
9 O) c% }9 c' T4 n" J6 s( e9 i+ f style_function=lambda feature: {
, P- R6 R4 w! D8 I# l" V/ i fillColor: #ffff00,
" X! ^: I) c% T6 M color: black,
; ~" ^* G0 H8 G& n, r' L weight: 2,5 I. C, q4 r; z* ^: E5 i. v5 ^& P, Z
dashArray: 5, 5
) r9 o; ]. o4 _( l }. R m) N8 ` z; _
).add_to(san_map)4 b- G. I$ K+ O
: i( s. e% Z/ I
#display map$ }6 g1 e5 T' K5 R+ {
san_map
# l$ h/ X9 \* H4 s3 q& N3 i
4 P8 ^: I+ v- M& k: \+ s! z$ t. j 8. 统计每个区域的犯罪事件数目
- r7 l4 @$ \* s( w O
# Count crime numbers in each
neighborhood
6 q1 y) {% \1 b# | disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
; O2 I7 t7 Q/ w disdata.reset_index(inplace=True)
+ ]& j8 p4 O9 m" h( a. p
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
6 I1 Z3 K7 s8 a7 H# m" G% I) J disdata
# b5 V0 F' y& D. j3 |
. ^: Y( L1 W0 l' t F0 b5 w( ?8 I+ s, c" s 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
' p9 L! i. S1 a" m m = folium.Map(location=[37.77, -122.4], zoom_start=12)
: q! p0 J2 Y: g: r. n q: a
folium.Choropleth(
5 J) x9 n4 Y3 E0 D* N6 u" V5 \ geo_data=san_geo,
6 T' O( L W5 }. J4 K
data=disdata,
0 R8 j% J- D ] columns=[Neighborhood,Count],
9 G+ \- _) d3 w6 _- i key_on=feature.properties.DISTRICT,
/ r9 W D2 {1 E0 ~0 e; w } #fill_color=red,
, ~, f1 w+ y8 T! Q+ Y
fill_color=YlOrRd,
9 [2 y8 C& d( ?: C: r
fill_opacity=0.7,
9 C9 L1 I; V) f( O M4 i line_opacity=0.2,
' n3 h9 m1 |( r0 E7 w9 ]8 V1 @ highlight=True,
7 k( f( C% Y* W9 Y* [
legend_name=Crime Counts in San Francisco
2 X0 j6 Y* j( @, m ).add_to(m)
- @, {7 ]9 r, s
m
$ W. S( Q, H6 G / z! [# L: S4 M+ B
i F/ a: p3 A
10. 创建热力图
5 I4 c$ X2 L- D
from folium.plugins import HeatMap6 F3 e# l, @* h: p
5 @0 M' _" N; B k9 d2 d # lets start again with a clean copy of the map of San Francisco8 K3 K! N8 ~7 Z q( ]! D+ H
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)0 V' h3 F% u% m' @" ^
& d* F% q6 Z& V, u: r
# Convert data format
+ [6 I' `; G9 ^, g3 m heatdata = data[[Y,X]].values.tolist()
: ]9 Y \! \4 i9 s! ] `/ b, a3 U1 V( u- k0 o' W! B/ C( f
# add incidents to map
6 l: b3 H0 l6 d4 C" O/ i HeatMap(heatdata).add_to(san_map)
y0 m' n1 [! L: P/ W4 ]5 h
9 h2 a' Y0 ?3 b$ B san_map
" M/ p9 l& }+ b, o4 x& x5 m) Q# B
8 U! p8 O9 T Q7 h. @- j; a( z, G 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
+ Q8 w0 |' j1 @/ }$ m) l5 u 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
- v) U( u# D6 H4 F
6 N1 E4 @# h5 l# R0 [
我的其他回答:
3 c- P' q/ Y( }4 {5 ~: C
/ C# r2 u- [' a8 | 6 G- a9 {( k5 Y- O
7 P( h- H7 A! |/ q: ~ 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
% V5 O. v" h! G; B0 h7 M
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
/ Q# [( O" L- u7 d/ P% o' L( x8 D! a 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
) `0 l+ D( Q% n 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
0 b) E6 M/ d/ B# c K4 ^ t
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
# V6 E/ ^4 a. m9 {, F; a