0 S1 i4 n" z" R' Q 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
$ f9 t; x2 K& D- N; N
" W0 W* H y( c7 ^, a n9 D$ I 使用方法很简单,操作如下:
导入包,创建一副世界地图3 E K! B, D( k; _" ~ k
import folium$ @9 i3 l+ x' N4 N& J' V
import pandas as pd& S( t0 x/ S( d) n% T
9 D7 j) p% {. b% B2 ` # define the world map7 j7 d2 K' f# X
world_map = folium.Map()* W( {# \8 m0 p4 m
! v0 s' }" E/ R5 r, T! Y1 o% p
# display world map* i2 a/ J$ ^3 I$ Q+ _9 |. {
world_map
; F8 M0 ~1 ?8 o9 A, F4 ?2 V
7 {' m+ ^. R! ~ 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
8 P/ N. W& A* U8 ]" D5 o3 }1 A" z # San Francisco latitude and longitude values3 V6 c' q. o, k% V. Q( u0 s
latitude = 37.77
* R/ T1 U' I, j/ S0 i longitude = -122.420 K. t6 c; D+ G2 g/ H* G6 t; ~
9 D% S2 L2 t f3 `7 q; S/ }
# Create map and display it
, d( M* A2 N& N- V) t0 V9 Z, |0 { san_map = folium.Map(location=[latitude, longitude], zoom_start=12), g9 k$ j" f* Y& x0 k
{2 {$ C4 A$ V r4 K # Display the map of San Francisco8 i; m; p# c% T \% Q0 R
san_map
5 k% ~$ ?! I0 B+ u& r8 A2 }
) c5 J" z/ d/ s 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
* u& O5 {1 Y& b& C- I: H
# Create map and display it
' j& c1 e% z. L1 y5 R/ X' l san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
0 k2 s1 S. k6 F3 ?/ I. X
+ h9 |2 o" E/ _9 \5 h 3. 读取数据集(旧金山犯罪数据集)
2 m, [( e3 K' \5 P% q' _# t # Read Dataset8 R$ c. `' n% G) l
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
% R- I5 @. ~7 T9 `8 A8 b cdata.head()
& Z% N& g; h0 D3 T! j/ w9 _
( C9 Q4 q. Z) }7 {& F1 D+ S 4. 在地图上显示前200条犯罪数据
) k* ~% ? A/ j4 j # get the first 200 crimes in the cdata
/ z% @5 e. d, l3 q: R limit = 200
, s$ G6 }! M) z data = cdata.
iloc[0:limit, :]
3 g! S6 T- n% k" x$ K. S
: {! g. H( D5 a f: L6 b* q # Instantiate a feature group for the incidents in the dataframe
* M2 l6 O. l7 V$ k* c% [% w incidents = folium.map.FeatureGroup()
* O/ n9 T1 m) N& Y Z# i! E! D: w4 |( Q- h. j7 V& z
# Loop through the 200 crimes and add each to the incidents feature group
2 \2 b G- b4 u+ d9 Y9 w( } for lat, lng, in zip(cdata.Y, data.X):
* U x8 x. i* v1 f( k3 U8 W
incidents.add_child(
7 C9 {: W5 s! X* \( W; b) a folium.CircleMarker(
8 m' a# K3 I {# U [lat, lng],
6 \, B, B" T/ p radius=7, # define how big you want the circle markers to be
( b4 L6 B2 ^% i, M7 B$ a
color=yellow,
2 e2 s n# Y' g! f f$ P) S2 T
fill=True,
) P7 P9 z6 u0 n* a/ k
fill_color=red,
# {; x9 |3 u# O+ p* S) j
fill_opacity=0.4
( `. ~$ k z v
)
$ X1 {5 \( n; E# H& N/ z )
; r3 U# W3 m5 U( X4 o2 E1 Y7 t: X8 l6 a5 P4 Y
# Add incidents to map
4 V% [9 L$ j& ?/ \( e7 z" ]& b san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
1 H- l' A6 V x3 Y san_
map.add_child(incidents)
. n) }7 N; {7 E) U8 a
; d. x7 U" _; |$ K; y2 q4 A& k 5. 添加地理标签
" y1 L5 s4 T" A* ?# b5 d5 s8 A
# add pop-up text to each marker on the map
2 o# k7 B; g8 K, B7 T
latitudes = list(data.Y)
3 n1 [7 J2 M6 E' T# v: N- ]
longitudes = list(data.X)
9 s- z2 X* ~4 T: n" c
labels = list(data.Category)
! ~9 Q3 J9 J o* V% j
# {& C- q1 V0 p7 s for lat, lng, label in zip(latitudes, longitudes, labels):
6 m/ ]8 Y4 O2 C
folium.Marker([lat, lng], popup=label).add_to(
san_map)
* w: n' K, \0 h5 `, K0 z- R2 j
# Y/ N' p2 n- O. H6 w9 ` A; g) ] # add incidents to map
2 A, D9 u# d9 a7 y8 H
san_map.add_child(incidents)
& O6 U) J. R8 s; D
7 C+ E% e$ T" |) c: q& }. l e 6. 统计区域犯罪总数
! Z9 c# A5 c( h3 @ from folium import plugins
1 B: |$ H. F6 C6 l2 d1 K
, X3 z1 _. O+ X7 Q$ t # lets start again with a clean copy of the map of San Francisco
d T' W4 ?" a9 x: [0 z san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
( z+ P1 V$ w3 }
9 d# k5 u; ^; g( m( K3 c$ O # instantiate a mark cluster object for the incidents in the dataframe
9 a7 x3 ~8 |# ~
incidents = plugins.MarkerCluster().add_to(san_map)
n/ Y" z' a# ~3 C: C2 `
% f$ ]9 D5 ?( r9 N0 y3 h, A
# loop through the
dataframe and add each data point to the mark cluster
& d8 s" T1 y( p+ u/ g& Q/ ^$ B6 Q9 O for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
2 z t) ~- H n& V' @ folium.Marker(
+ _, }% e- _7 a7 H6 `/ ^# G: H
location=[lat, lng],
" h- ?9 @+ [4 q5 O; D. Y+ q+ _ icon=None,
# |, I% t- M2 V- q
popup=label,
1 h# R+ c# d( v% \. c; W3 E ).add_to(incidents)
' T$ z" y8 n- q1 u+ t$ f
2 v( m" O# O# [* T# `7 ~2 D3 [6 k # add incidents to map
/ D6 z' m5 w3 B3 _6 z- _
san_map.add_child(incidents)
- [( P7 A( ^! Z: t# j% G' M( [
f6 d4 k# }& W: [' T0 } 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
5 @9 d" f9 {+ x( k7 x- D, T% p import json
8 Z) k# N6 D" J } H import requests' p5 Z" }6 F# @
: B5 m: h' n% m url = https://cocl.us/sanfran_geojson
2 b; B% W V& I g# [ san_geo = f{url}
s; z/ S5 |3 W3 U; U0 Q6 \" F- O san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)) V2 M; y* a4 J3 T5 r0 w% k
folium.GeoJson(
% d' Q0 E0 R/ Q% p" M0 F san_geo,5 J* u/ n6 B: Z! S, |: ?- B
style_function=lambda feature: { r$ z8 T. L6 z5 \- o( I; n* e6 D
fillColor: #ffff00,
5 j# x- `! D" I n) T/ `, L& N color: black,
# ]9 l! R: k$ k8 t2 O weight: 2,
3 Z4 F1 _+ `, b3 o: J8 K0 W dashArray: 5, 5: e/ d5 D: Q5 y0 _( z6 y. Q
}- u$ x2 I7 G0 y* C
).add_to(san_map)
0 `* A+ _- u& j5 p) s3 o7 O
; R0 f' C- k" t' d/ b #display map4 ?9 x& r. h& W" A0 x5 i% y3 x
san_map
" X- }0 f! G" y7 F3 z/ w # s, Q% y. W2 ~- Z" h
8. 统计每个区域的犯罪事件数目
% U: P: }1 Z# B# e+ E # Count crime numbers in each
neighborhood
M( ~. n( t) e* Y disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
+ h( y# R) G4 W& E; k- p
disdata.reset_index(inplace=True)
0 t1 E9 E5 {# a8 m6 ?- s* W7 b- g disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
4 Z+ ~3 m7 F- i: U9 l1 F disdata
0 e7 T! r: r% ]6 D; E. w* S
+ U: ?' C6 t" y: c1 | 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
8 r! z3 Y: B9 @ O0 E L1 d K m = folium.Map(location=[37.77, -122.4], zoom_start=12)
' }: n- o9 c6 V* k8 J. X: f1 m3 \ folium.Choropleth(
( p3 [3 `' w, }+ V geo_data=san_geo,
1 w4 d/ y1 L' @
data=disdata,
8 v1 I( i9 E4 s' V& Z columns=[Neighborhood,Count],
, L3 g4 s: q( y- D1 Z key_on=feature.properties.DISTRICT,
. N0 e# w# o7 K7 E- `& _7 Z* P #fill_color=red,
( O% p5 x( ^& v& X0 K! D% j fill_color=YlOrRd,
4 h& Y7 a- N6 g+ b1 ]# j) R
fill_opacity=0.7,
) ^" p9 v1 I! V2 ~. C line_opacity=0.2,
, z& {! L) d2 A/ A8 r, E
highlight=True,
6 S( t m" T8 R9 @; B legend_name=Crime Counts in San Francisco
6 e, y" N7 |3 T- _3 G
).add_to(m)
( u) w) e2 H! X. D( m1 d( C m
+ \- t# F* v+ { a' G' L7 K6 I
6 m$ v: C# m4 C( F9 Y5 f# X7 t; @- h , a, K; ~5 f7 g. _, x& R9 e
10. 创建热力图
7 F1 @5 v, X$ O- p
from folium.plugins import HeatMap
% M' ?2 j7 @2 n `9 `0 Y) U
, K& C" _9 v0 V( H. X3 g # lets start again with a clean copy of the map of San Francisco
|- C' Z4 i1 [3 x7 D+ y san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)/ Y/ f0 G) c, d4 h$ G1 p- G/ g9 o
& b- l Q0 d, ]7 N& C- s& j
# Convert data format2 V3 D6 B9 e* I6 _ G
heatdata = data[[Y,X]].values.tolist()
% K2 o* q5 _4 K1 t. c$ G; F) ?5 `6 e y: U
# add incidents to map
]0 x, b# f3 B" p8 z/ ? HeatMap(heatdata).add_to(san_map)/ k. I5 W* j2 l! ?
! ^' n ~# l! U) b; q2 k5 |6 u8 T9 S san_map
$ j5 a4 a- c+ T' H+ j& E 9 J) l6 f0 q3 W
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
3 }+ U- N7 T, Q& ]" v
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
$ e' O8 l$ K& X( G
! D; O4 V+ k: o6 e8 k5 g
我的其他回答:
! p( v- A2 m* ~ ?
% l2 p2 E& d8 H) }3 z. D% B' @1 A* [ , _$ c5 d3 l' e) I1 x) [
3 H7 y' L# A) ^, c B* v& C. V 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
6 ~4 n8 h9 [& E9 Y2 w
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
7 _/ S. e9 c/ p, D& e! ~) B 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
/ s8 j2 N! m* E% X/ b* f0 t' B0 v; ^ 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
; C. f5 H* {7 O! J
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
$ t, F1 O3 v; L8 z3 U0 w. |* p