: t- I! r V/ t* \9 ? 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
! t6 P+ Y) z- F1 q+ t& _3 L) i) K
5 X! |9 S8 _& @8 j1 Y d6 Q
使用方法很简单,操作如下:
导入包,创建一副世界地图$ D0 C: A7 R, t! U+ n& K) B
import folium$ E; d" A }- K% W5 d/ p# N
import pandas as pd
) r- s3 ^& T+ C- z; V' ~
4 i8 e9 b7 V/ m # define the world map
R0 k$ ~2 U7 k8 \ world_map = folium.Map()
5 X9 t9 h" l2 W7 K5 N; |
$ A# u& ~4 l$ Q+ l' h4 w ^; j # display world map
) V7 V( M( ]+ W/ R* B) U world_map
m0 {; F; X1 z' Q3 F0 m& S2 J2 E" [ ) o! |4 K2 o6 I9 Q5 U8 F) n4 y
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
% j0 q1 _$ M6 c* e9 ?* p
# San Francisco latitude and longitude values- [5 @" P: B; f' P
latitude = 37.77
- ]- ?9 y# I" v6 C" [6 k. ^* V longitude = -122.42
- z, B! `/ ]" \4 Z
. j+ d$ B6 s& I) X # Create map and display it. M5 k3 J1 K- ~/ [, n" m
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
. L! Q# K3 E% H3 i
1 R3 @0 r8 f( {5 V+ H # Display the map of San Francisco! Z: \" I( h, _) R4 W. T
san_map
" B1 P5 E: r6 T: [* q8 q - h C8 K* I- m5 ]) g
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
" L9 A8 Q) Y( u. g' @ s5 ~& e # Create map and display it& x: N# w2 U, F7 Q1 ~0 Q7 R
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
% f* V/ T7 @' U
% B# w+ \: \" @ 3. 读取数据集(旧金山犯罪数据集)
* a$ i! U/ L; {3 X" }
# Read Dataset- x) h4 b, I/ v: t
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
- G1 B: Q2 q7 V* J, d1 R cdata.head()
, J/ [$ m, U2 i0 P
]8 q6 q2 E6 G! h 4. 在地图上显示前200条犯罪数据
R- D8 Y& ]& K$ \
# get the first 200 crimes in the cdata
2 U7 |# [9 d$ z& w limit = 200
& {$ S# Z6 y0 ]2 F7 |7 A ?
data = cdata.
iloc[0:limit, :]
9 `- P+ e5 q# o) Y6 w m
4 ~) j5 W# |$ K0 g, n* }
# Instantiate a feature group for the incidents in the dataframe
/ Y8 d% u9 k4 ~0 n4 K' r
incidents = folium.map.FeatureGroup()
5 m O/ z: r6 ?- |( a! y7 n. F* Y( V: B* i, V
# Loop through the 200 crimes and add each to the incidents feature group
p+ R( P7 I; j for lat, lng, in zip(cdata.Y, data.X):
9 ?6 N* G0 N, U3 X, _- X incidents.add_child(
7 Z# c$ U2 l, d4 d% W folium.CircleMarker(
' V; ~% z6 s6 z: E' p, j+ \
[lat, lng],
2 c1 D% k5 M2 O3 f radius=7, # define how big you want the circle markers to be
2 a9 K: H2 C& x# r2 J# R7 k, \* f
color=yellow,
T- J( C* o0 m8 I: `$ _0 ?- e( }" ?2 ^
fill=True,
( z! Y0 v1 i M% d fill_color=red,
6 o8 f0 l8 t- T
fill_opacity=0.4
& X% w8 ^0 n3 i4 e0 j ]0 q
)
5 c. E- L" v- T. b- s' Z$ k )
- L# D/ ?# E1 i5 O W* H. Z# h" \
& X" l* _+ \; ]2 a9 M: f6 d2 {& d- B # Add incidents to map
2 i' M- I) O" c7 @2 `; A( q
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
( O, n) f! z& K1 B! [) y. r' x
san_
map.add_child(incidents)
& k/ K. s) ^# \% _& t! U) `
1 h; [1 d( {. g/ B+ ~/ h 5. 添加地理标签
$ V6 p% o! Z) j2 x
# add pop-up text to each marker on the map
Y3 |$ g7 c) I7 S8 I
latitudes = list(data.Y)
# ?5 V* h' |8 a% u$ }1 T longitudes = list(data.X)
' _' w5 u2 z/ K
labels = list(data.Category)
( C* a( W4 \, _" K# f. A5 r& m
% b& S) ^2 Q, X! o for lat, lng, label in zip(latitudes, longitudes, labels):
: o7 {9 h+ w; |, Y
folium.Marker([lat, lng], popup=label).add_to(
san_map)
2 }+ w. v9 a& `. @$ P
1 l' S0 e8 f/ `2 v. ]! E6 K. r& { # add incidents to map
8 T4 ?4 J2 V* M) A# `1 M" R' O% D3 R san_map.add_child(incidents)
5 x. N, I% k: W- K5 i" k
9 Z) J2 O! [6 Y$ k 6. 统计区域犯罪总数
9 j8 c( c, e$ [5 q4 M from folium import plugins
( C8 O. n- x4 a/ @4 d+ k. e6 l T- T7 a! F* E5 C( Z
# lets start again with a clean copy of the map of San Francisco
; I/ }3 r7 v: e2 I/ \ san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
6 w. J( T1 S8 Q" w' {& f
- k9 `. z( A0 U# Y$ n% i # instantiate a mark cluster object for the incidents in the dataframe
8 L- n9 \3 m/ h) J
incidents = plugins.MarkerCluster().add_to(san_map)
0 o2 J6 _; r: [( I+ j7 {3 x, }6 e' U4 x( q
# loop through the
dataframe and add each data point to the mark cluster
$ p- [9 O% n5 F6 N
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
- Z8 i9 e" D- V) ]: c" _' S: K folium.Marker(
- |4 Y" |0 D0 c& t4 T! U+ p location=[lat, lng],
9 ?: C) e: i( J* W- F5 m" a
icon=None,
' R+ ^: U3 Q! i+ ], s8 C
popup=label,
$ l1 K* I" l/ \7 @( |8 E4 O ).add_to(incidents)
2 x; J! s/ X6 [. W: ^/ G
$ B# m( S, d7 [. x
# add incidents to map
! O9 S6 s2 d+ K1 O% P: h# o san_map.add_child(incidents)
+ E, J" r( N& k4 y; b
0 I8 s, y/ G; C8 x6 ^ 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
@' J) C* h% H/ L1 E" c( M+ f
import json
8 }6 W P5 \% u. ^- v: b import requests
6 c# d4 f* p& s. Y: M J
2 t+ S4 j1 d7 w! x' D* x$ z url = https://cocl.us/sanfran_geojson
& U: g0 ~! V* s. D% H san_geo = f{url}7 R: C. P4 ^7 n3 C: M
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)6 V5 ?$ V& ~# |5 K
folium.GeoJson(6 g+ C3 L ~8 H. |
san_geo,
4 N% d6 Q9 ^. R/ i& @* ~ style_function=lambda feature: {
4 [' G; y% e. a2 c6 Q. Q fillColor: #ffff00,! q/ F5 v% O9 `" I; r; e9 b
color: black,
$ j @. W) d* b' _ weight: 2,- g1 z0 n) J7 q6 M. |6 o
dashArray: 5, 53 j- }* R1 v7 v2 o' \4 c* G4 T
}! U6 e2 q2 j, t
).add_to(san_map)
' `; P, j$ C* L5 L- W; d1 X6 ~0 }( d
#display map- G8 m; w3 j3 Z9 w9 C7 n
san_map
) o8 T8 a) e" R& t+ M
+ @3 v, ]' A8 G- \
8. 统计每个区域的犯罪事件数目
6 y% C1 ]- c3 [2 ` _9 T # Count crime numbers in each
neighborhood
' p; `& C' N# t disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
3 {: J/ a) J8 ~% b/ Q; V, _
disdata.reset_index(inplace=True)
" m3 ]: I/ C& c disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
, _$ b' |( a4 C7 w. q) `" C disdata
+ ~8 k4 s1 _' j0 `
! ~; ^( B2 w2 E4 { 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
0 f9 `6 ~8 b7 K m = folium.Map(location=[37.77, -122.4], zoom_start=12)
6 e( T! R/ X& O E+ ?, i# v, L$ @ folium.Choropleth(
4 K! i5 U) k" \ ?/ \" Q: X8 o
geo_data=san_geo,
0 h" m# x; u- g! g3 E2 _
data=disdata,
# ?7 O3 J" o( }5 F" K# v columns=[Neighborhood,Count],
; e* q8 Z" w0 `
key_on=feature.properties.DISTRICT,
8 Z3 O! W, A7 F O _' a #fill_color=red,
( v9 X/ H. J* Q1 Y& ~ fill_color=YlOrRd,
: G( k# B! J* v3 \/ ?4 z fill_opacity=0.7,
. z* R* h* I. U6 `; x line_opacity=0.2,
1 `0 C4 P6 W* E7 j! |! L! t
highlight=True,
7 C/ g" }) d. ^2 p6 ?
legend_name=Crime Counts in San Francisco
q. N8 K& x$ d ).add_to(m)
" x3 [# f/ b2 d
m
6 o" X' U( }: Z0 G
5 X8 G( s+ M" U8 T/ I2 n8 w3 j
: F* c( X" }9 v. f( g a 10. 创建热力图
/ R s( Z4 o1 t! y0 e1 n% i
from folium.plugins import HeatMap
" _" k1 c% j; Z; S+ I9 A$ O( R6 m1 g: y7 c1 Q6 i+ ^+ C6 }
# lets start again with a clean copy of the map of San Francisco6 x# s1 O# T5 Q5 Y( [# C1 u& P2 V
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
5 Z9 [: h/ _( R$ O7 R0 {- I5 f1 L+ ^( c8 M8 `) a& H
# Convert data format
8 ]" A( Q: Z, P; {$ n heatdata = data[[Y,X]].values.tolist()* f, f4 S) y# T, ~- p, ~# w: i
8 y+ z) d6 {; o, ?* E/ x% ?% T
# add incidents to map
& m% G( w0 `) U( J# w, N2 R! o8 i; } HeatMap(heatdata).add_to(san_map)
. \, T {# ~0 K e& p/ T
: t% X$ W- K: W6 k2 I M' R( y san_map
) d. \9 a8 W( ]8 G) ]/ f
2 ^8 W4 o5 O: X
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
4 r6 u3 e. \' ]) M* A0 B6 _& J
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
% Q i% ?! f8 j! L( n
: z5 `' ^0 g' Z; l; Q2 {# t
我的其他回答:
1 R$ \( s" H' ~ f0 L" ? ) Z; h3 p% @# M8 O
* g% I/ X7 T/ \4 I8 @) e8 r5 l
( O9 _1 M, c- o: Q6 i7 j% A
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
; N0 ?: ^" _2 {) ?& }& u! B6 P
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
/ L: ^( F! S: l# C" a( d7 ~+ v 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
$ @- S2 d, o/ j. O 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
! A) @1 ^& O/ I; Y Z- u- l' ` 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
0 t% b& t2 f/ C z