- T! [2 v/ c( R, Y+ b 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
% P5 [. i( j. x7 h+ h% R7 y 8 g' B2 s1 _; [8 s3 n8 L
使用方法很简单,操作如下:
导入包,创建一副世界地图
( `: s! z' }9 }2 Y6 D/ { import folium% A6 S* [" \% V
import pandas as pd
; S: z1 V! l8 C6 B+ P
$ h5 j8 U* m! |' C # define the world map% z9 T5 U% B" I9 P. B; a
world_map = folium.Map()
8 L& D- T( L' u- _9 G& J
% O: P! ?; S. Z+ M4 e" q! f. c3 Z" o # display world map
y% c) o7 D0 S/ u world_map
9 e0 k( i/ u g0 G% }
% u+ u7 s W f; \) N5 m* w. B 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
6 F5 C9 w8 j6 C) q4 n
# San Francisco latitude and longitude values
; D6 i6 T8 w& ?& _" K latitude = 37.77+ ^! q; k& P9 O& k5 x. G
longitude = -122.42
/ i! v3 j1 o9 H2 ?6 I; o1 H
7 n' W4 x1 ^/ O8 [( e- B # Create map and display it0 H# F* x# h9 L' [$ f
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)8 v1 }4 B+ ^' `& F/ l( {, N
( u) c5 n/ Q5 d2 V+ x1 E$ A # Display the map of San Francisco
: i% h2 n! z9 _( J san_map
& g+ b* W2 w7 a. P+ o% G
- U. ]' T' J5 s& x) \- ] 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
1 c# ^( w/ l {6 x0 F # Create map and display it
! ^( _0 R/ L9 w! `) E san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
* U' h* m+ d1 f q
) k3 p- |6 F; P# O. o& e 3. 读取数据集(旧金山犯罪数据集)
3 q/ E6 @1 t; a8 X' {5 R* S% p # Read Dataset& W, U! I) \3 n
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
# Z7 r& j% \9 {; w0 M `" t cdata.head()
h% R L1 t: E$ ]- |0 L$ y. @ , \* Z& X' R9 B) h+ J
4. 在地图上显示前200条犯罪数据
" x& }/ W0 {0 p- L! v; v$ @2 Z
# get the first 200 crimes in the cdata
/ F: D: {) L6 _$ w
limit = 200
% M- {1 W; u, l) i
data = cdata.
iloc[0:limit, :]
- I: o+ k$ n3 w( h( d4 O* s# G9 t) O) ]+ X/ K7 U
# Instantiate a feature group for the incidents in the dataframe
9 U8 D5 M. c) k' A, @. `4 F4 z
incidents = folium.map.FeatureGroup()
. F" @- Y% i$ p
4 t. z) s4 W0 P1 X
# Loop through the 200 crimes and add each to the incidents feature group
7 L, e/ s$ d6 f9 Y- Z# v6 P Q2 ~ for lat, lng, in zip(cdata.Y, data.X):
* u8 E4 x1 N* O5 Y. I
incidents.add_child(
( E/ b$ @' \4 p% ` folium.CircleMarker(
* a$ w8 }3 T; o, g+ S3 B$ I
[lat, lng],
( ~# `+ c( Q: p$ W6 d' n radius=7, # define how big you want the circle markers to be
2 X% N1 {& ?# ~# [ color=yellow,
; e6 E$ J! `2 y fill=True,
* y8 o: k( x* B: e
fill_color=red,
; x3 K* J2 D' {; n. h; ]' m, P! V
fill_opacity=0.4
3 G3 @& y& M/ Q4 Y
)
( t$ {/ T9 ~2 v2 B# [# o )
6 M$ H6 A+ g$ e! B1 @# A. I& `$ S* Z6 x, @; Q
# Add incidents to map
4 }4 c0 K% F1 I K! U7 r1 c( O4 [
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
/ {- }" ^/ R; d5 C$ x9 x" r7 @5 h
san_
map.add_child(incidents)
9 K+ p+ t" K* C% ~ * ]6 g' ~2 |0 V) C4 Y. [
5. 添加地理标签
- f+ g7 w$ ~/ w1 [! v3 Q # add pop-up text to each marker on the map
4 {2 b0 Y6 ?- h! {8 `
latitudes = list(data.Y)
' F2 a8 Z8 B( v5 s h( a& S
longitudes = list(data.X)
0 C$ r# C) c9 K# L& O" U" p labels = list(data.Category)
" x- D S& M8 N3 M" q* g" P
9 y% S0 x# B- y, i6 b m4 e
for lat, lng, label in zip(latitudes, longitudes, labels):
2 d1 x* R, c G7 n, ]# G" @+ F folium.Marker([lat, lng], popup=label).add_to(
san_map)
1 |6 U8 P7 T! P5 b5 l9 F6 z! a \9 ^7 Y% g' V6 j
# add incidents to map
9 H& q* @3 F& | san_map.add_child(incidents)
1 t6 @7 ]2 { E. X; Q
8 p" s8 n+ n; F7 @
6. 统计区域犯罪总数
( a1 b% r& ~7 q2 ?
from folium import plugins
! L5 R9 M" C, k6 A+ q, o3 P- B! T" M
# lets start again with a clean copy of the map of San Francisco
1 B8 N" Q' |- [8 P$ o" F san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
1 G2 @. J1 C4 _3 N& P/ D; {6 ^, \% M' ^2 L: [4 L1 k
# instantiate a mark cluster object for the incidents in the dataframe
9 u; l) ]4 Y* v7 R8 S' B4 q incidents = plugins.MarkerCluster().add_to(san_map)
; ?; C; k5 }. L1 w
9 @3 m8 s+ z9 F Y2 ?
# loop through the
dataframe and add each data point to the mark cluster
( Y+ p! B1 G" f# U for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
' X4 {" ]0 H: R6 N5 B; C folium.Marker(
U: H" l4 R2 ]) K location=[lat, lng],
8 o& z* ~6 I$ P1 n) I
icon=None,
5 H7 p. s+ ], b5 y2 o# U
popup=label,
2 W+ P/ T1 T% {: K% p. L+ [9 `/ h T
).add_to(incidents)
* j+ x2 p) q# {2 m
6 Z5 V: {6 _2 d # add incidents to map
F/ w% \0 x% _! J2 e% b san_map.add_child(incidents)
* J1 E C/ _, f
: ]$ h- T# s! M, `+ U; F 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
J2 \$ S. d: \* ]. x6 M1 i6 ]1 p; H
import json2 ]1 P, V2 s+ k/ z5 t
import requests
1 k' H0 _' A M, I: J% k# N. ~! X+ x* \) z) ^
url = https://cocl.us/sanfran_geojson
5 G* Y2 v# A! [" |; @. O san_geo = f{url}
+ X# k: f- v/ i3 V san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)4 z" A5 W& A! X6 |$ J
folium.GeoJson( C8 S+ X8 P. p( U5 a
san_geo,
) y& a8 u# ~0 L6 ]) Y! m2 a* I# | style_function=lambda feature: {& ^2 k4 T3 N3 O
fillColor: #ffff00,
2 l0 ]% j* Y( J& c% @' ?3 z+ G2 `% b. o color: black,
" }7 F) p/ G, w5 X3 e% a weight: 2,
2 |; Q. d U& ]- _) Z) [' }- z5 a. c dashArray: 5, 5
X4 n" {. ~- g- \, K }+ V4 q# Q% }$ a
).add_to(san_map)) e1 R$ s# X2 z- A
4 ?& D6 [8 N( R, t _ #display map5 c( [! a0 M' Y: x" O' P
san_map
% a: |3 {; c7 @2 c/ E; E
4 ]/ Z( b2 k- [1 c0 P. x3 f 8. 统计每个区域的犯罪事件数目
! W7 u4 b9 p7 ?' K# p) f8 X2 H
# Count crime numbers in each
neighborhood
4 `; `0 K- ~/ E- M/ ~5 {) b5 M& F disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
; i& I3 k4 S% T8 L5 T% K# W; K- s' t
disdata.reset_index(inplace=True)
$ y! }% \1 b+ D. m7 C1 C
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
. M4 _$ h# o% b* T" w5 z% h
disdata
8 U9 Z. k4 N+ J
. w5 }3 y" h4 _8 T! l9 G 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
2 J% W+ W# H7 Z$ ?( S8 Y+ _
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
! m" p8 q2 c1 @" p9 [ folium.Choropleth(
. ]$ m9 U& \1 U: W( x7 T9 ?
geo_data=san_geo,
0 e2 L7 f) W8 h! j
data=disdata,
# g- v' n8 }8 T0 w0 V* l$ L! D columns=[Neighborhood,Count],
) e' d, h, u0 E. y7 ~; W- r7 n key_on=feature.properties.DISTRICT,
3 c* o5 R1 Q5 R" s. T( U3 w% v* Q( W #fill_color=red,
3 h( \- i" U/ G9 j# i/ y fill_color=YlOrRd,
# b3 @& h" F" K5 i1 w& U
fill_opacity=0.7,
, f, a$ u/ A! V3 y! \# x
line_opacity=0.2,
& U6 l7 K7 f. ^- H/ T2 ^0 F1 `. B- f
highlight=True,
; a/ j% c$ L8 b8 C6 T
legend_name=Crime Counts in San Francisco
1 C7 @; D" H6 C! d* h2 D" r4 q9 i5 m ).add_to(m)
7 G2 N, ]4 w b% a- j2 K# d7 O
m
2 V( l/ p1 a3 U3 i1 \2 W - F7 J8 u( f+ j9 n0 H9 A" u
% b% V- U1 @5 z) r" J5 E
10. 创建热力图
/ x1 x; p2 y5 j" b from folium.plugins import HeatMap
* Y, w( Z9 {% M# g! W2 Y4 \! R' k
# lets start again with a clean copy of the map of San Francisco) h& L1 x7 c6 S* B& t
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12). c1 b. v$ {2 c9 v, E( i) k
+ j) T; W1 h6 C1 N0 l) S- W+ s # Convert data format1 r% q& G3 Q9 R- k0 |* Y! @, g( j$ |
heatdata = data[[Y,X]].values.tolist()9 v. B+ v6 _9 g" y& J% ] t5 h
( T8 d" ~/ R! h% @' m7 Z l& n # add incidents to map; M: ^# d8 P! \6 v6 V* |
HeatMap(heatdata).add_to(san_map)
) }! X- u% _" [/ q, p/ C8 ~; H1 d8 W& Z3 y# c6 |8 i4 e- _. C0 s$ N _
san_map
% l# F! m( c- Q! o
; K) \9 n0 g5 Z0 Q" `. {% \" q7 [: l
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
8 [0 `- O8 k- [/ V, i# L 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
( s- ~8 r m( {3 t! b; \$ a 7 {3 Q8 x" u/ e1 e% @( [
我的其他回答:
; _+ Y# b! b2 F" h5 x9 \
5 |7 s# ~, v, b4 N" { * B7 D: b/ a2 Y6 ~/ d
! l' J {" W3 I& L! i
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
N* E* W% g) F 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
# G$ j @2 Q) F9 L' b 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
) o6 m- J, O) A, z# H" z; ^ 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
% _0 o, r" v, Z( Q6 W- M
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
: [! m0 H# }3 f: d6 x# s/ D