/ G4 ?5 W. n. S( S 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
T" l) W p: M8 I2 G' `. Y. r- S - m! n U. N) u
使用方法很简单,操作如下:
导入包,创建一副世界地图- r/ P( q2 E3 f/ q0 B. t
import folium$ Y8 Z- D% K! S
import pandas as pd
7 h& b% D3 \0 c# U2 {
- D: c. a- _ Q" z+ \/ }5 ~ # define the world map$ B9 S# H' v `- W9 j& E
world_map = folium.Map()) [. G: R4 a. A \
0 n* Z/ w$ G& E # display world map
/ H; X$ E6 C. y5 |% L& r world_map
. T8 [9 X9 V: G8 d
4 q; y* ]1 J' }6 M9 Q0 I& R. ^ 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
+ O) |; n' \: S! u' Z2 A. m* \, u
# San Francisco latitude and longitude values0 o7 W0 x4 ^$ w. l
latitude = 37.77* `) @& c( D( u
longitude = -122.42
/ c& s1 p7 [8 l. G% {
( V2 ~3 y3 ~- p: F4 }" R: {: r # Create map and display it) I) k. G/ [2 O# K2 F2 `8 ]4 N1 f$ @# I
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
/ z4 w: e( _2 N! C6 X5 n( Q$ i2 V/ i* c- o" k( }- F$ H" a4 J
# Display the map of San Francisco
9 R8 p) s& s v( J& u san_map
; w/ h+ Q5 i/ S3 D* ^! O V
' c+ b# v0 j6 b- l; l; u 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
. X; P, X6 _7 i, {
# Create map and display it
7 ?( G7 O; x: B, o san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
+ ~; B2 }- `+ C! w' {7 w/ y' K
1 Y- v" b# B! X 3. 读取数据集(旧金山犯罪数据集)
6 K, A4 k; Z0 A- ^/ b0 c
# Read Dataset
7 B4 Z, N0 u8 b2 P cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
! G4 {9 t% @. ^. G3 m1 x cdata.head()
7 {- W# ~/ G M0 g; Y) u% X
3 C+ h' Y' D) n, S" p
4. 在地图上显示前200条犯罪数据
% \, D* _4 F- x9 f6 C/ T9 I" F # get the first 200 crimes in the cdata
5 i9 R' e3 i7 I [& k" Y9 i# t& A8 r limit = 200
2 i5 M' x6 E$ \ E! c0 V, I7 I data = cdata.
iloc[0:limit, :]
: {0 l/ Z9 ?- [2 N6 R! ]
( u" P: I0 d4 {7 x. u0 y- W" K( Y # Instantiate a feature group for the incidents in the dataframe
2 I0 [0 W" E9 K$ ?1 w, x2 g/ f# H
incidents = folium.map.FeatureGroup()
9 h3 b" h" N6 r8 Z. ^2 q0 ^9 O9 }* d" r0 h' d8 g" d
# Loop through the 200 crimes and add each to the incidents feature group
* Y& ]2 n$ B$ J
for lat, lng, in zip(cdata.Y, data.X):
6 `; h! V/ u6 b- T7 P8 u
incidents.add_child(
0 H4 Z) G/ w R& n
folium.CircleMarker(
& Y4 u4 Q2 J5 n& P1 f7 h3 u w0 W, S [lat, lng],
/ s. j0 Z/ K \) K! Z* D
radius=7, # define how big you want the circle markers to be
* P4 m" C3 d+ c
color=yellow,
% B4 \) |; [7 b0 q: }: w3 U) Z fill=True,
* n; r2 w# S. c0 g3 f) ]* { fill_color=red,
* R, Z- d) S/ B fill_opacity=0.4
* H' k0 |9 M) G2 }. k9 D$ x K
)
7 F+ i% Y y+ F )
+ g# b( C) J* g1 \ U x/ h
& r& Z3 v( ?) [- G; x8 D # Add incidents to map
! o& H# w; b; U$ y: H; A san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
) z% b u- w( n2 T; g/ R san_
map.add_child(incidents)
: ?# b4 ?) h" v5 |3 U0 C
: g ^1 A, V" q% O# U0 T* _ 5. 添加地理标签
0 k$ l& c1 x$ m1 ]: l& V3 O
# add pop-up text to each marker on the map
' T+ ^& G" z* _2 ?0 x& n latitudes = list(data.Y)
; h5 J) _$ R2 {& U: S7 Z# D
longitudes = list(data.X)
3 e2 `6 L& n4 f8 {
labels = list(data.Category)
0 x( `7 k8 h* b. H
6 A* X; [) ?+ { J; i" M
for lat, lng, label in zip(latitudes, longitudes, labels):
+ S# e6 ?9 e+ t( B folium.Marker([lat, lng], popup=label).add_to(
san_map)
/ R" A2 ^( f% n9 r* y. |8 y
+ N6 w6 p' {) I1 {9 `5 w" C # add incidents to map
6 r$ D" l4 V6 J3 k9 k" H
san_map.add_child(incidents)
* G8 s- e7 J/ I! A' J
) Q$ L; k9 s; V, i& s' P 6. 统计区域犯罪总数
p4 U9 ~# u( I6 M) Q# F3 u# ? from folium import plugins
& Q) i& {9 D i9 D E+ j0 H
2 O8 m5 z" J9 {, ~+ a( G # lets start again with a clean copy of the map of San Francisco
; b b8 F2 Q7 g
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
2 L/ p) m h `/ @" \/ x2 `
( g8 S. h' @7 M6 W # instantiate a mark cluster object for the incidents in the dataframe
9 V7 i* H1 O/ i! J8 n6 ] K incidents = plugins.MarkerCluster().add_to(san_map)
# @) s/ x* ~* @1 |8 F
, w# I1 K" ] I0 J # loop through the
dataframe and add each data point to the mark cluster
6 @% N6 Z( A( ~+ F8 K for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
/ t: \; T' h+ c K3 G o
folium.Marker(
1 ]& _3 Z4 g! Q& F9 N: c location=[lat, lng],
1 s( S2 I; G3 n" s icon=None,
$ c, m2 U- Z3 _* U; u
popup=label,
& j3 V) V) l: v, n( w' I5 j ).add_to(incidents)
7 x% D9 k* a) U3 c* z3 G& [4 c
# C9 ~4 \/ I& `0 | # add incidents to map
- f; h. O! s% ~2 N
san_map.add_child(incidents)
! t9 o! K: R% n# X' J% W
4 x# Q# S( l8 Q: R, z 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
9 x! i9 f) ], T: r import json( w9 P7 t l0 ^3 [' y
import requests
# e' ~2 [* d& l/ b" e. R4 w; y- o( q$ f: \+ {! B" J
url = https://cocl.us/sanfran_geojson3 f9 G7 o! Q) d
san_geo = f{url}# v: V% p' K8 I0 x: N
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
$ r, M8 ^5 T, l$ ?3 z0 @- ] folium.GeoJson($ k6 O& t# q0 {, t L
san_geo,' ]/ f: I9 k" i8 f" i* z1 e
style_function=lambda feature: {
( i0 C0 M& l5 E% A* h8 p; D fillColor: #ffff00,
t( S% x9 `6 g) G color: black,! a( L4 e* Z. g
weight: 2,2 N, D! M1 ]" Z0 ?
dashArray: 5, 5
/ R4 Z# e% O5 ^ }! t, a3 k! J: O% A8 W- j; T
).add_to(san_map)
& e5 d* v. J5 o3 s$ V" }' b( y( e; K" t& F
#display map
8 d/ Y! F' L7 J san_map
0 Q+ X! q+ `+ `3 {5 J' ~
: M2 v% Y2 b/ D8 q+ E3 o* k 8. 统计每个区域的犯罪事件数目
$ n1 t8 F' T" a# U
# Count crime numbers in each
neighborhood
0 x: l5 L: j( K; U disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
5 _. F& |$ N: }5 \4 Q3 y9 F5 i disdata.reset_index(inplace=True)
. Q/ E* u3 z p$ t. I6 M disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
+ U7 C4 o4 m U* y disdata
3 b1 d+ Z7 ~$ ]$ M6 E
" Z& P* a. q& i 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
" N( D, j: b3 r& ?' Y9 _ m = folium.Map(location=[37.77, -122.4], zoom_start=12)
5 E2 |8 \' w8 R: }5 x _. h
folium.Choropleth(
; M( d; J0 F7 X* ^9 [# t6 d geo_data=san_geo,
$ ~: o+ H- v/ F
data=disdata,
0 {2 b0 Q- h& @: h8 N: [4 R6 x columns=[Neighborhood,Count],
; w9 u1 y# g1 e
key_on=feature.properties.DISTRICT,
& w( y1 I$ g- n! R6 x
#fill_color=red,
# B; w0 l# M& ]4 N4 Z
fill_color=YlOrRd,
- u+ b0 ?5 m5 {* Z fill_opacity=0.7,
/ J" b1 L8 N0 X1 L' i line_opacity=0.2,
( _# p/ E$ V4 e& d( b highlight=True,
$ W. \1 B Y9 d* }3 n; G legend_name=Crime Counts in San Francisco
/ Y6 v" C5 ?% y9 j' c
).add_to(m)
) n/ g9 b3 A/ m' r& x$ g) f
m
9 ~2 M. \6 E$ n2 b& [: l" E* t # J# G0 b. I. M/ E9 W1 b/ C2 m
+ M0 _% T4 `& r! X 10. 创建热力图
( e0 w0 E6 P, S5 D: z8 M6 i% s5 B& G
from folium.plugins import HeatMap
1 m9 W. J: H: j9 _
9 s2 p6 v3 J" C0 ]3 H+ U k # lets start again with a clean copy of the map of San Francisco( `5 @1 v5 x6 F" r2 w0 B9 R1 L
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)/ o B, {% b6 J
X7 D. U; _1 d- `
# Convert data format
1 \2 W: _* G! g& Z1 W9 F heatdata = data[[Y,X]].values.tolist()
5 t4 f4 w6 T# G. P# f1 Z; C' ]) ~5 z! L. @; T: Z' m- ~: g* }
# add incidents to map
/ z5 f# a' t$ b6 ` HeatMap(heatdata).add_to(san_map)
) r* w9 Z0 G& d/ _
+ C$ O0 s/ z; Q2 L san_map
4 ~0 g. C- G/ }% q5 Y
# i9 d6 p- e) }/ y 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
7 c5 l/ G4 n$ W. U V 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
( i: O7 N3 {- a- v" }1 k
9 p6 P* ~( H' O5 B
我的其他回答:
0 X4 {0 v6 z2 z, _/ x2 H+ I$ h# c
* V# |6 g T* a+ o4 A 9 ~. l/ b$ j0 m; C- [
% h. {6 c0 K# p: v; X/ b 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
- d$ K& y. @8 m 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
' v* O/ F, C0 P2 y; o
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
/ k4 Y% W+ [/ n$ i3 U* V9 `
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
% o: h ]( \( w! T2 w 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
" j; W D- f5 d