( ^* _( R" p, H- q, L0 ]
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
- o6 p# F4 ]7 M0 x
& }% L! H" T: ^2 d8 ?5 @5 |; ^; a 使用方法很简单,操作如下:
导入包,创建一副世界地图7 R: T! A P( c7 @2 r
import folium* }# V, J3 T9 p4 x
import pandas as pd4 n3 {1 S9 e' ]) w! V
* N+ o7 s, U7 M# G! Y; @" R
# define the world map
: a& Q7 x* G: l3 \4 }4 S$ J world_map = folium.Map()
% \- k0 k9 `" B' r
6 l n0 A# Y0 i0 V # display world map$ @' D: k6 p' K
world_map
6 Z$ E- Y1 l, G( X
6 H- m0 Q3 o7 X) b4 [ 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
1 L2 B7 Y# P+ F- J6 b6 W' M
# San Francisco latitude and longitude values
( T8 i. O; F1 W$ [/ S% E1 { latitude = 37.77" n; ~2 T9 a! A
longitude = -122.42- y% M, A z) v; Y
" c2 _" M9 I1 V Z) F+ O9 B- c
# Create map and display it
. ]# s) Y5 a3 ?4 u" M% J san_map = folium.Map(location=[latitude, longitude], zoom_start=12)* T1 l3 d1 O5 p3 a; U$ N( z
0 k' v" U# t% O1 H9 K6 N
# Display the map of San Francisco
! B" F9 t( P) ~! ~* Q, h: Z( F: _ san_map
4 {3 q- ]4 j# k: u9 C' Q 0 M6 `- e/ w3 [# r; \' l7 L0 b
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
" P! K& k" r, W
# Create map and display it! e+ }6 }6 `6 W- d5 _
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
6 ?( C$ R6 g9 D$ X
" @5 G( v2 b2 T; A
3. 读取数据集(旧金山犯罪数据集)
" W* g% D+ d" j$ s # Read Dataset
" K" p5 ~. V2 J" j( F5 |! {' Y P cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)( g8 w' l" Y L" Y: C( n3 B+ x
cdata.head()
, q3 Y; D+ w" N- R4 V: O
7 u W! `" l5 u7 L! @
4. 在地图上显示前200条犯罪数据
9 K) S7 I! c) r2 H" E # get the first 200 crimes in the cdata
% ?* k! J! z4 w- ?' p" T [ o4 a1 n
limit = 200
* P2 N% [" Z0 \2 Z# ~ data = cdata.
iloc[0:limit, :]
5 S+ e9 s$ {1 Q! S
( Q( v$ `5 V8 E! H' F- G/ e$ i$ m- z # Instantiate a feature group for the incidents in the dataframe
$ K! q" C8 O2 ` incidents = folium.map.FeatureGroup()
s+ |$ f, z* g8 j5 g& i2 x4 X* i/ q) h
# Loop through the 200 crimes and add each to the incidents feature group
; \' x0 _; v8 P for lat, lng, in zip(cdata.Y, data.X):
0 C, j- Q8 ^# N+ D4 y, }0 r
incidents.add_child(
+ f% \: }" i4 @1 Z: j
folium.CircleMarker(
$ O$ K- a% W- @! \' \; L) y4 S+ v% z [lat, lng],
: S. B6 O+ V1 |3 W* Y radius=7, # define how big you want the circle markers to be
: K, z" |0 t+ o color=yellow,
& y0 \& g! f8 M O! v
fill=True,
* d' q6 `+ U; k t, A; [ fill_color=red,
$ O4 G0 {4 @$ V- A8 f. f
fill_opacity=0.4
, m9 Z0 s- R1 t )
7 \* C) c' _; [
)
* v) P$ b" }5 ^1 f5 D* Z) ]" H2 t. p2 n: u, I
# Add incidents to map
0 _+ g0 s% n) r# S- t2 J% N) n san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
2 _+ L/ i, ~( v' Y5 v0 R. b$ _ san_
map.add_child(incidents)
( a6 M+ V+ P$ M% J$ e
0 g4 B3 j0 t4 k" g! V 5. 添加地理标签
/ s1 h G G. c* z6 k8 | # add pop-up text to each marker on the map
1 T7 u) x1 V- K latitudes = list(data.Y)
3 ^8 r0 |) ]( U* \0 ?& t longitudes = list(data.X)
) I6 o/ D- n8 X S labels = list(data.Category)
/ F' @: z1 Y' A o
# C5 t* S6 |8 E9 F( T# X7 `
for lat, lng, label in zip(latitudes, longitudes, labels):
/ b: [" \ P4 p/ B3 M
folium.Marker([lat, lng], popup=label).add_to(
san_map)
: w8 }7 I/ u1 y+ O7 Q' c: V+ H0 _+ z3 U- G( a
# add incidents to map
1 t" [) v6 _3 b5 m san_map.add_child(incidents)
6 y$ f# @. |8 T8 }+ \! |
9 H' d n4 ]# _( u4 X' n, L 6. 统计区域犯罪总数
' g, } |% J" p from folium import plugins
% c, c0 D* L. F8 n+ H
h8 s' s- ~4 l, O- S: |0 o # lets start again with a clean copy of the map of San Francisco
5 }( W+ X3 E" Y8 h8 [5 A
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
( W5 [9 q6 t8 @
! l. S0 m8 e- _3 r7 Z8 z # instantiate a mark cluster object for the incidents in the dataframe
! _$ S! Z! x ?6 O% ~ s/ Y2 g
incidents = plugins.MarkerCluster().add_to(san_map)
% ^$ z& L5 p+ b1 u' x& N* K
, v/ i/ I" u6 l$ Z # loop through the
dataframe and add each data point to the mark cluster
8 ?! [! X- k G6 H3 p for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
9 G' y4 v+ J% v3 M/ Y
folium.Marker(
* _! ~8 K5 o E, J/ \
location=[lat, lng],
$ {# Q) F: L0 q9 D7 f icon=None,
4 B' F0 x- z# a; D- B
popup=label,
k6 [. Z' M F, j4 A$ b2 g N
).add_to(incidents)
5 Z# J$ I/ p& ^. v0 g) Q, [: h, c; K8 `6 G1 Z+ N' o- l+ R! k
# add incidents to map
c% a. L2 d9 A0 B( r$ c. i
san_map.add_child(incidents)
/ ~6 u2 X/ t& ~9 f7 Y9 J
9 `+ `( R/ ^% p# Z1 n7 T
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
( U: g: J$ A* U" n* N/ k
import json
- }# n. O& @1 B }+ M import requests- X. q2 |7 z5 V3 X
$ m3 K' A6 ?9 @( H8 |6 \: _
url = https://cocl.us/sanfran_geojson1 ~" W$ Q, @5 z) f) i
san_geo = f{url}
8 |+ P+ M' N8 x* ^7 o+ x san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)& R8 i& Z7 q* u5 Z" p
folium.GeoJson(/ f; B' `' y& K i6 w5 L# C
san_geo,+ y, p+ {3 S) Y ?# [
style_function=lambda feature: {
* N* f4 N2 @/ d% n3 @$ I fillColor: #ffff00,
( \! s& Y5 i' S# I color: black,9 |! ^: F* u" s" f# P" I
weight: 2,
) @9 C! |1 @: D, q# J dashArray: 5, 59 N: x. ^# F; G7 y' d
}
% o: R- k C5 j! p ).add_to(san_map)- B: \! R+ c, E, k6 d5 O
3 i; q" h( q' |5 V #display map- L5 m2 {$ Q: m
san_map
6 C+ I1 b( J: \7 \- l* S
- b% I. Y d c
8. 统计每个区域的犯罪事件数目
# Y9 L7 }4 `3 T8 q1 s$ p5 ]6 y
# Count crime numbers in each
neighborhood: X6 q! A# k2 r9 k' U6 u
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
6 T! b& J% C' L( S+ F+ U9 L% L9 C' d# e
disdata.reset_index(inplace=True)
/ Q1 F) O2 l0 d7 A
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
, B% f0 ^ j2 R" J disdata
# ?$ r" g5 l) S; Q1 U( A
m+ K+ y, Y7 p( n9 A. U
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
' T6 z8 I: e3 ^! f) I m = folium.Map(location=[37.77, -122.4], zoom_start=12)
) g; K/ T6 ]0 t ^5 c$ h( p6 C folium.Choropleth(
+ i/ g/ M8 L- G/ X; E3 g9 ? geo_data=san_geo,
5 a, D' J1 B7 r, P2 g data=disdata,
9 b) C# _% t* F9 P: d9 w
columns=[Neighborhood,Count],
1 A* C% B6 h$ e
key_on=feature.properties.DISTRICT,
2 m; a1 s1 ~6 r! a
#fill_color=red,
& w# r/ O" C, W* O* q fill_color=YlOrRd,
& M9 v S* x2 G& @4 }
fill_opacity=0.7,
* U4 Y" G" Y# I7 p
line_opacity=0.2,
# w& @& m) A$ v: _ Q$ T& m highlight=True,
. I0 s4 g9 M! g2 P1 _. S legend_name=Crime Counts in San Francisco
8 g' G, f) b U4 s, X4 l7 Z ).add_to(m)
5 N5 @ f, R7 k' z: I' i* ?' a m
, G$ O9 O& d1 b' C# ~* }9 p: c M
* `. Q1 X! |8 k' t, {2 M; x
( Z0 t% E% m1 r3 h 10. 创建热力图
9 t: B. ?3 ^7 d2 ~0 ?# T
from folium.plugins import HeatMap
. m. t; d6 y' }9 k8 v9 k9 u
- C6 D* |% s0 F6 G, ^+ ]; r9 K4 @; I # lets start again with a clean copy of the map of San Francisco
5 Q" `! z) s" x" I. `: J2 o2 e san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
* H- T/ {1 f# `4 H4 l/ ]9 q
, Q& U' y' G# a& M # Convert data format
5 {! H& t/ {, B( ~6 u0 P$ } heatdata = data[[Y,X]].values.tolist()
% c4 M0 O; G5 P. m4 d
- X0 H. O- {; V5 `' } # add incidents to map
1 E+ r- L% ^6 y6 K, K+ T1 T* C' _ HeatMap(heatdata).add_to(san_map)
" y) ?6 |( ^' _# g8 C- b- f7 F
2 o7 n& Z5 f! U) I+ u+ n$ \ san_map
& C4 d' F* v, T% [
& G% z8 g, `( [* s0 j 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
/ \+ S& X( G* I; S 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
! y% o+ l/ `" g! T9 e3 Q; s4 I3 B ! j/ y' G4 N7 A% V7 m9 f& }
我的其他回答:
: y5 Y9 t4 x4 r S% B, N
?( ~0 F4 J. ~3 Z. l$ _
; l/ y$ C& W; q$ S$ B: z
( N# i! z8 R. R( o3 F; Y 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
, ?& Z: A, N8 Z! K: Y* }) k. t 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
$ m' h3 U& i( b: u& I V6 N, c
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
5 V9 U3 A, R! p- ^' P; J 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
G7 _) p! ^ |
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
1 a! E% }5 I9 ?1 a3 @, ~) s) ^