- l- p/ h, o3 Q& u5 e 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
7 n6 D. C0 u6 g- S
4 ^# U+ d- w s7 H 使用方法很简单,操作如下:
导入包,创建一副世界地图, l5 j/ z& d3 D$ d* F) _
import folium
- U. \2 c' e0 ` import pandas as pd7 K( | x# i- C& w
% l" E7 ~% J& c7 N! s # define the world map% o/ R* O2 G8 U: m+ V+ T/ F
world_map = folium.Map()
/ I4 |# t, ~' n) ~$ e2 [% _+ t3 ?4 N* v( C; k4 W
# display world map
) u, Q! u. H+ b" i world_map
) Q: }: x; N M: B- E& }& _' o& I
, w' _8 p. I& L! y3 C0 g0 |! | 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
7 @) j- y5 G4 o5 N5 m # San Francisco latitude and longitude values
- k* b; D [/ G9 B# y/ D latitude = 37.77
* K1 R; f/ k) z. q* X7 p longitude = -122.42
! S% G1 J4 o6 n
+ |* K5 o+ }3 @/ L; u3 i # Create map and display it
% y2 p) y9 S) O; o# h# u san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
G1 A7 d5 d R/ p- k0 ~. V* P4 I% }) v% B* @9 g8 {' e
# Display the map of San Francisco* r F5 [! N2 b# o
san_map
% n5 U3 N* T' c6 h3 E8 e
+ Q3 p. d, \7 o8 f" T
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
3 Q5 R5 R) v0 K: ^' y
# Create map and display it
7 @% r0 L! Z: X5 f0 ` san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
# b1 o0 l4 o7 X% x( x- n) [0 }4 z ) o9 ?9 S$ z* _. q' V( I
3. 读取数据集(旧金山犯罪数据集)
: M) l7 C5 i! z% m& S0 ]: E
# Read Dataset
! l6 Z1 Y; a0 |7 s: B1 i8 q cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
( E' Q8 A4 u8 ~) ]/ q, X4 r8 H cdata.head()
& [9 G% A* \& E, ]# ] x
& W3 C9 Z# N8 s% {6 g
4. 在地图上显示前200条犯罪数据
7 E0 B; @* T+ t& s# e, l4 ~- m
# get the first 200 crimes in the cdata
6 b4 E: C9 L7 @2 ^ G limit = 200
; l3 C# a6 B$ k3 L3 |8 n data = cdata.
iloc[0:limit, :]
1 ^% e5 u- |* f7 A3 y8 A
: J Z7 R9 a' q$ H/ b1 u: n' n
# Instantiate a feature group for the incidents in the dataframe
5 a: ]/ y. n/ S; Y# |$ R0 C2 G
incidents = folium.map.FeatureGroup()
6 r6 F" v+ n+ P' `+ b
3 I/ U/ N( L' N- }6 c
# Loop through the 200 crimes and add each to the incidents feature group
6 o5 [* f9 c) K$ z! J
for lat, lng, in zip(cdata.Y, data.X):
6 e {3 W+ e! D( j+ a
incidents.add_child(
- }& }$ i4 w4 m& E) R9 e folium.CircleMarker(
9 m4 H4 @9 n9 H7 T% I. @ [lat, lng],
# z J% `' M! ?4 w
radius=7, # define how big you want the circle markers to be
7 `) Q5 T; |" o8 e color=yellow,
; X. L& F- ]( u( h
fill=True,
4 }0 a8 m! s2 } m6 u8 y fill_color=red,
1 E7 X6 R! [! B: a6 N$ A fill_opacity=0.4
' @6 X0 v3 ~! v0 E )
4 G9 C, h- g$ T. G
)
. E% [8 E3 N6 D: e& O+ F" n& t Y( s) h9 {, u
# Add incidents to map
+ F* _" z7 z9 P: E6 R) c2 q7 h
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
) @! C3 e" s& V8 b
san_
map.add_child(incidents)
* w! G% _# j. e& M
/ |- u8 J/ `2 L7 p1 d/ E' Q
5. 添加地理标签
6 z5 C( S# L* p; n* V5 h" i' M( U* c # add pop-up text to each marker on the map
% r2 I5 t) ?% W) u9 A+ ~ latitudes = list(data.Y)
1 \5 d1 w4 v2 k/ w
longitudes = list(data.X)
' q" r; m. t+ E: o) F- a1 Y' r/ e5 U
labels = list(data.Category)
' q0 r" I# m8 U
; B o" {) |( o( E* {, y for lat, lng, label in zip(latitudes, longitudes, labels):
$ r: c9 S, m; C" _) b- g
folium.Marker([lat, lng], popup=label).add_to(
san_map)
2 C; T4 j0 G1 P H" A
T& e) V# n0 Y, Y# p* x # add incidents to map
) Q: Z) H7 ]9 M' B/ _
san_map.add_child(incidents)
1 N. l- V8 ?! ]: a 5 [. E! \6 @# s0 ]" T
6. 统计区域犯罪总数
2 e- `3 ]7 k/ `7 T- N& n- U2 e
from folium import plugins
! Q) y: ]# F A: U+ `; S
. ~2 T5 {) X, i' T: u
# lets start again with a clean copy of the map of San Francisco
) J" [* n4 f: ~* M5 l' d, S! I6 A" { san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
0 ^8 |' O2 M! u! h# G, r' I1 F, y
! x D; k9 d" s }# L7 T
# instantiate a mark cluster object for the incidents in the dataframe
! ^6 W/ _! h( }& ^
incidents = plugins.MarkerCluster().add_to(san_map)
2 \ [7 B4 o; T4 n) M
& m2 g# [# S; U7 a # loop through the
dataframe and add each data point to the mark cluster
& a3 Q, U3 ~+ U& }& `$ ~) k H/ _
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
) ?- g3 W0 y* _2 Q6 e9 ]$ X6 O
folium.Marker(
}2 p: G- _) x! [( D location=[lat, lng],
( U) Q8 g/ d; P: T/ `3 e1 e
icon=None,
9 u% O8 \- _6 }- p Z3 R popup=label,
8 ?6 t* _7 |! r( C ).add_to(incidents)
$ f2 k; ^. `% R& u# w: }( b+ Q, P, h( E9 `7 `+ {
# add incidents to map
; @1 Q4 c% \. n) e) g+ t san_map.add_child(incidents)
2 @0 S/ s: z- v/ A- @2 N! c
, i$ ]; z: N9 Q
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
/ J) U4 J7 B4 F& r import json3 e7 _; @% c/ e7 R
import requests
% }5 v6 p% ]2 S5 C0 h6 c4 C8 j! P5 `5 e2 Q3 a( }" |
url = https://cocl.us/sanfran_geojson; x; o3 o8 h( j: v# J. l ^ Y) b
san_geo = f{url}, S# C6 \$ s% d7 v! b2 @
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
" S* R* ^7 v+ m; e; n$ V% b4 d folium.GeoJson(6 A: \ y, T' ], ~" M5 _. l
san_geo,
% \) P6 H. J7 | style_function=lambda feature: {
, d; M& M! |3 ]7 D7 Z; v fillColor: #ffff00,8 U ~- _; f3 s% {
color: black,: \1 W1 m! m1 F0 x
weight: 2,
. d, }( T4 y( f dashArray: 5, 58 q$ F7 I$ c6 Z
}! R7 W/ L6 u2 M' @4 o0 n+ s$ d
).add_to(san_map)
5 B, B, g1 a2 H+ \% C# M0 n7 W( U4 V5 u
#display map! I! g g4 m% K& S
san_map
" `) R+ D! A9 t( L: k
2 G, b1 ^0 m( Y' i. @ 8. 统计每个区域的犯罪事件数目
* N8 t6 m' K9 s1 C # Count crime numbers in each
neighborhood
, w; o4 N& N) w2 Y; R/ p: M disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
3 H) L, a0 n" a( R& A disdata.reset_index(inplace=True)
9 }1 I! c7 H8 B7 X2 Y
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
& F$ m' U* ~0 M disdata
6 ?$ y9 |( V3 x, j ! u- Y2 x" N) y6 B9 ]
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
+ z" p6 `( s) P' n* }7 v4 o0 \( Y m = folium.Map(location=[37.77, -122.4], zoom_start=12)
# c2 S. o, y0 T6 q2 p
folium.Choropleth(
! ^1 L' a. Z0 C/ r/ i# l geo_data=san_geo,
0 i+ F$ v# `: i data=disdata,
5 ^9 \( d0 M7 p6 G" h
columns=[Neighborhood,Count],
" e! @" R0 S7 w key_on=feature.properties.DISTRICT,
6 d; p+ A9 [" f7 Z& c #fill_color=red,
2 u `& X, }9 `2 j' |4 M5 i4 ^ fill_color=YlOrRd,
7 w; l" A$ E2 |: B( Y l fill_opacity=0.7,
+ `; c6 s- S+ k& N+ |: t# X line_opacity=0.2,
; m$ a1 [8 h# V; T0 w; I7 n' G5 l highlight=True,
( [, B/ ^+ m& c# Q5 b6 _
legend_name=Crime Counts in San Francisco
: Y) e# E- D$ L |' \
).add_to(m)
. S0 T+ j; ?% L; V$ n
m
5 g3 S$ |; p# x4 ^# T$ r2 f$ A# K
2 `- h6 L6 c$ i* y/ {( B * v$ O& E( w$ L8 U
10. 创建热力图
4 S7 c- Z1 q6 B a
from folium.plugins import HeatMap
8 v5 @( M/ n: F
( |% {8 w7 L( X0 v1 J/ e' | # lets start again with a clean copy of the map of San Francisco
4 K# ~% v( P) b! P2 y2 } san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
9 q, ]4 C& |& k. @+ |1 S* @5 r' Z- y) q& K9 x4 p
# Convert data format4 z# H5 j. M8 c/ L4 _& n
heatdata = data[[Y,X]].values.tolist()% l* p) F+ C2 M5 \) [% F! O, H, I) |
4 I6 ~, C* W4 G4 @ # add incidents to map
: B, k3 y4 c1 M4 c* [ HeatMap(heatdata).add_to(san_map)
0 Z& ?0 V6 s* K5 g
P8 E( n# L% j0 s% d san_map
$ U: k6 n" `& ]' b9 Q
& Y2 m, h" I/ ?! M5 i 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
, z" P' f/ a" ?2 u2 o% m8 B5 {3 Q
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
- X2 L' u: ^5 C, F5 i
. x" d. \" k" @
我的其他回答:
$ K; m& H# P) d+ [5 h: t4 _0 B
& _( d# U0 d* e" ^) C* [ 6 V! D2 _3 c& _+ ]! M
8 L* l5 [& c4 V- P- i
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
8 i* j' o( p4 C0 A6 ]1 X3 u 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
5 `) w6 b, H- W
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
# Q3 y( z* ~+ X0 D 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
" J3 J- T" c% |) n
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
( y7 {9 Q; o8 `. l# v