! U2 R9 s8 K: Y
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
+ z/ I, ? ^3 F
$ E/ v4 J% S. ^+ e) M0 \. b
使用方法很简单,操作如下:
导入包,创建一副世界地图# ^2 [: Q, {# d
import folium# r# Q# s7 ^3 l6 E! L: m! G
import pandas as pd
- Y) K j& J2 h" o8 M$ M% Y
; P. F c# B, \- K" _$ S1 g # define the world map* F3 {9 z5 ~: u" l% F, m* {/ v
world_map = folium.Map()
- Y& \7 K& y" r) J+ U+ x
. H9 [" k6 `+ O6 y" ?4 k # display world map
4 g- L; U' z/ F, k world_map
2 n# T0 ?* P: I4 b8 _, I' g
" q( n2 O4 g! h 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
' Q. O0 ~) J( }% E2 d% _+ @ # San Francisco latitude and longitude values2 r+ y+ v9 U# I. \
latitude = 37.77
* O/ H- d% Z1 m longitude = -122.42
- G# {' p& y3 g% L, C
8 e ^( c7 d/ l a3 U7 R$ H # Create map and display it+ e6 D/ E$ V z: g
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
7 O7 f7 i0 L. v6 q4 y/ f
9 p+ Z, z7 f# E2 |0 s1 d# T # Display the map of San Francisco
; L' h8 d7 ?& P7 n3 P$ K san_map
, e7 q2 M; m' h2 b" G4 g6 {
' B/ A/ \ w* c3 V: h2 V
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
3 g. c) F, ~, V
# Create map and display it
9 l; l" `' M6 y! n; {" B( T, i& u4 u san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
* x l+ N& ?& X7 c& E( O5 _
7 w5 q7 Q; H; U. @9 U# v) \
3. 读取数据集(旧金山犯罪数据集)
- f6 \8 O6 a0 n9 Y E: R # Read Dataset
0 d6 ]( \5 U+ q0 k: M" K cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)- M8 T; w$ M* \3 j' I
cdata.head()
/ H" w' I1 [3 J r
3 Y" K0 H% ~7 K6 g; j 4. 在地图上显示前200条犯罪数据
, ?- K- v" L. {9 L # get the first 200 crimes in the cdata
; Y: Z$ H7 k' K6 e4 b9 j4 y
limit = 200
% ]/ N$ [, L$ @' y& c data = cdata.
iloc[0:limit, :]
( |: M0 x S( K7 }8 c. t( w o% O' k4 [+ d2 O F$ ^
# Instantiate a feature group for the incidents in the dataframe
6 N5 e7 R6 O1 f9 O& Y3 ^ incidents = folium.map.FeatureGroup()
! Z+ r- H6 ~, U5 l
' j4 o, E/ s- R$ G" ? # Loop through the 200 crimes and add each to the incidents feature group
( n8 T% ~4 z$ n$ b, O7 k
for lat, lng, in zip(cdata.Y, data.X):
$ s' n$ z4 d) C
incidents.add_child(
7 \# q( h" |% l$ i( y$ R$ L8 V folium.CircleMarker(
8 n7 L5 @; u$ s
[lat, lng],
: G7 {, B' W6 G) W M/ F- D; }
radius=7, # define how big you want the circle markers to be
4 G0 t! _7 {1 I color=yellow,
# t6 V j i$ x4 x' ?$ z$ f
fill=True,
8 J3 ?# g u8 R( w, r
fill_color=red,
! Q* W7 [* r. S1 ]1 b) C( A3 w0 | fill_opacity=0.4
2 f* o6 U8 C& B
)
1 q9 G" |, x" I: g# R% v )
9 O% E" G6 X4 B5 `6 ~% |* U
! R8 {& Z C7 N+ H' ? # Add incidents to map
! i% A( Z6 z( \& p' m/ ?
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
- k/ ~; v; y* e' b
san_
map.add_child(incidents)
. b7 d+ y! k7 l/ S! L3 V5 S( U
$ A; b' @1 i2 j: D0 a4 i
5. 添加地理标签
3 |5 |3 k* c: M0 `: @0 o' N- H; @
# add pop-up text to each marker on the map
" E; Y6 A% Y& j0 ]3 B) o latitudes = list(data.Y)
: C$ q+ Z5 M/ }
longitudes = list(data.X)
9 z. A |! c+ }/ {8 B
labels = list(data.Category)
: c7 K7 \! D0 [$ \* t
" d& R; r; `8 r" ~2 H2 F' y# T for lat, lng, label in zip(latitudes, longitudes, labels):
. @( Q- t) N) e! O- l% v) ` folium.Marker([lat, lng], popup=label).add_to(
san_map)
" D2 p" ]8 Z: x6 K5 @: }8 h9 e
5 n; c! J2 O2 } # add incidents to map
$ ~% g7 R- X/ Y) S6 L+ ?
san_map.add_child(incidents)
" L8 f" u4 o/ v; F + ^8 [6 k7 M" F( ^+ z. w P* M
6. 统计区域犯罪总数
3 `! V6 j$ i( n' d: s
from folium import plugins
4 z( ?% r9 C& b0 J9 p/ j$ @: D* o6 x% B& K4 g
# lets start again with a clean copy of the map of San Francisco
. T& P) @4 h6 `2 @0 l( ~& T san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
3 a$ L+ C1 Z; Q& u
+ I: a4 D7 A4 S: X/ G # instantiate a mark cluster object for the incidents in the dataframe
2 h+ b; t9 n3 ^9 u) { incidents = plugins.MarkerCluster().add_to(san_map)
8 K* u: i" `# H
) V1 T; {7 Q* p, f8 | # loop through the
dataframe and add each data point to the mark cluster
1 m4 a' @& F- J5 m- K for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
4 v/ H/ ~) q5 i3 _ folium.Marker(
- A! U. ]7 Z, Y) k- M T
location=[lat, lng],
% h- C8 a, A/ b6 B6 s! j
icon=None,
; ?1 ^+ q2 t% x
popup=label,
0 K! }6 _. m0 O% Z
).add_to(incidents)
$ [& U) s- e$ b9 y
4 o' g* K* j4 @; z n/ `) b5 g6 f
# add incidents to map
5 e; [2 A- y1 H p6 e4 L4 T4 A
san_map.add_child(incidents)
# M% P1 @, h7 Q. Q
) M i: ]8 L5 P2 D
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
. o* \1 W* A; w2 g/ c" z
import json
8 D: N+ b8 `3 c+ x import requests2 u3 X* O+ Z& K
4 s- x' U9 G7 k% L$ G# b$ C
url = https://cocl.us/sanfran_geojson
$ Z- y9 e) K' T- ^/ ~ san_geo = f{url}
2 @0 O, Z8 G2 K d' U san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)3 C2 W7 o5 T! j0 C9 `$ f2 }3 s
folium.GeoJson(
- h- \ R6 o5 _$ y san_geo,1 q6 P: P! X0 q* u
style_function=lambda feature: {; P) d% b6 ]- m
fillColor: #ffff00,
: y. w d" a: }5 a4 q color: black,
) ]5 q7 D' f# l% u1 f) [- S weight: 2,3 Z+ N- ^0 `" |
dashArray: 5, 5
8 {$ j1 y6 u7 z1 s }) O) \: v0 o9 ~) J% W. Z
).add_to(san_map)7 E4 A" J- }- k$ |! M& B2 ^
7 Q6 J$ S6 c' C! O! ?/ Z' ~' h+ L
#display map: _8 Q0 p" a* a! }5 y* L
san_map
% u( n1 X0 D% o+ a5 b9 Z 9 i! l' y; U \
8. 统计每个区域的犯罪事件数目
! w. D+ {3 X6 |, z( [
# Count crime numbers in each
neighborhood
6 K* d$ X3 G- x& Z% u0 ? Q3 q" K disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
3 h ]) L4 `: R: z7 i1 C: z
disdata.reset_index(inplace=True)
, M; k6 }5 k2 c8 L3 A& R disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
7 G7 w5 a; E- q: R; Q, z) P
disdata
6 r" J$ }! A% y' }& T* i: @
* r' S. U# ^ K8 _6 }! q 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
7 c% s0 P2 J) a! h" I
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
1 \8 F7 N8 p5 q7 F/ _# I9 x% D folium.Choropleth(
* C$ W7 c, a' ?. o( k: _" y geo_data=san_geo,
5 @1 L3 {2 r) n data=disdata,
& S/ K$ k& I. ^( O4 ]! F
columns=[Neighborhood,Count],
: @ Z, c5 T- A2 O9 T8 Z0 Z
key_on=feature.properties.DISTRICT,
( L2 V. F4 D+ y& i+ L
#fill_color=red,
4 S# w+ y- _$ @5 w9 m, W K" q
fill_color=YlOrRd,
# {- u2 y3 o% Y# z) ] fill_opacity=0.7,
+ u3 E+ `& R" I+ A" L) `9 ?. j0 P line_opacity=0.2,
; j) m* y5 a6 w1 e2 b
highlight=True,
& J% H) `/ m- _9 K7 L4 T% A legend_name=Crime Counts in San Francisco
. q* K: p) _' x/ F6 I, O ).add_to(m)
# k+ \- h) n, G m
2 T; E) ]8 q' V- M" c5 E
8 F1 S) X# X. E) K8 w * y$ i. r/ c1 m
10. 创建热力图
. N: }5 c8 ?/ h! L5 I/ K from folium.plugins import HeatMap0 Z# P/ j) \6 X6 F. V G
A; N) g t, P- V3 a. { Q. M
# lets start again with a clean copy of the map of San Francisco
- v8 S$ I* A" e san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)" z" d: C/ G# Z
! ]5 |. b! E8 [+ V) j+ p' q* r) @/ u # Convert data format
1 i7 f" c! y1 A% R$ k heatdata = data[[Y,X]].values.tolist()
; N8 ^7 `- K2 Q
! A9 R, S; y2 O: x+ b6 s # add incidents to map
6 Z/ J, e$ Z) f HeatMap(heatdata).add_to(san_map)- {5 O$ X+ T! z, a, B
: Q" e+ n+ e6 r! J$ v( Z
san_map
. R8 _. m0 `6 |0 T( ]% | $ s: l/ B2 V; C8 z
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
5 w6 r6 S C9 d+ K5 Z T
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
/ C6 Q( g' k0 w/ P, y8 O) e
; \% y6 D& N w. ^ 我的其他回答:
0 ]. O# Q% ^. s5 W * g# [$ |8 k9 M$ x
$ y! K7 X" f) B6 y: ] ' _/ ?/ {6 y! o+ W6 B" Z% ~) w; V
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
6 q, ^: p9 t5 C$ V
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
/ f" `' o. m$ Y$ V! t# s/ W5 ^1 L5 p 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
' Y! E5 k! X, M n. @& g2 J* `
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
# d d4 I9 J1 I
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
% m) H4 V. @& b& `