) K) x' ^( f: ?2 O' r; q
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
- l3 F8 r7 e+ u. n% v$ r
( H: u, s. l+ R% w* a" @: P( T
使用方法很简单,操作如下:
导入包,创建一副世界地图) Y2 s" J+ C' b% R9 b, P
import folium) y% }( {6 Y9 N2 f6 T
import pandas as pd+ e2 ?( g0 O! z0 _
1 z; K% _+ {: g; H: y R
# define the world map
# S" k7 N' k; ]" F world_map = folium.Map()
) l$ [" X' z3 t6 N4 c
& _& C( F& O* z! J# P # display world map" n) }+ g) a& Z" ^" K
world_map
+ V- @$ K! Q4 t# b4 i8 ?% H3 d
! h; x5 F2 c/ ]* ^$ u+ h
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
; ~: a& ^6 J" e6 r7 }2 L, Z
# San Francisco latitude and longitude values+ s# H3 {1 Z, \* _
latitude = 37.77
! y" T& {; c! O B0 S7 @$ } longitude = -122.42
; R/ E P; L8 k8 o$ b
1 k1 E% j; n- i4 c, M # Create map and display it) U# N# j4 b1 X& j- e. \
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
' f: \3 I6 p6 k7 \; E+ m( O2 m3 {4 b" m2 J
# Display the map of San Francisco
( y4 R% ^) d6 J$ F& M, \( n san_map
* n2 D" z; p0 A- j7 o6 a+ w- O5 n9 U
$ \, S% v t! X* Z: @ 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
6 C; ?* W7 R8 E' [
# Create map and display it
3 E. U( k \: K: h8 f san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
9 t% W8 c6 b2 q4 E0 ^" ^4 X
( e* U4 D8 I) k- r' A h
3. 读取数据集(旧金山犯罪数据集)
: u/ o" u4 A8 H' M4 r' J& T! E # Read Dataset7 a& R$ g( C9 b4 S
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)( _1 y O* I1 x5 [
cdata.head()
3 c* P8 e0 J0 H0 ~
# c `, g& Q" \* i 4. 在地图上显示前200条犯罪数据
1 C) a$ @0 B& T* [* o/ K; R
# get the first 200 crimes in the cdata
) r B* w2 W+ F I limit = 200
: v/ v3 o6 q; Y% A2 b% q( L) a2 n
data = cdata.
iloc[0:limit, :]
% _2 w7 g& N' t/ V' Z- U( @* D+ t. T8 T' j
# Instantiate a feature group for the incidents in the dataframe
# |: ^1 E, E: T' U7 ~4 l
incidents = folium.map.FeatureGroup()
' K% G7 B% Q; m/ {
3 ?+ }8 |: t' n3 I+ T# k, l # Loop through the 200 crimes and add each to the incidents feature group
% ~& @( q6 U$ F) O ?8 u1 V for lat, lng, in zip(cdata.Y, data.X):
8 l* T, }+ ~% ~. m+ M1 X" ^ incidents.add_child(
# o$ P ~& q( v folium.CircleMarker(
# E7 e5 G! W2 o& y" X- U
[lat, lng],
% l4 y E' O# e; l% H radius=7, # define how big you want the circle markers to be
; P; c+ A3 R- v& y6 N( n, n/ R color=yellow,
: k" b% k- T5 L2 X! ?2 S3 r0 B
fill=True,
( H/ M) {) [- }" u$ ^6 t' U& F fill_color=red,
4 p2 G) z8 s+ `$ m* M$ C8 ?8 H
fill_opacity=0.4
+ ~9 r. w) i2 j- [* h( \ )
" W: l8 `; H2 s3 l- G# ` )
5 `" m3 x2 M! y4 Z1 S8 S: A; v. j& ~6 r* P M: p& i' o
# Add incidents to map
- D* `, h! F5 \' |% M h% w4 j+ G5 q san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
+ n* m% L8 O. C/ t
san_
map.add_child(incidents)
' s/ a6 g2 w6 ]% v' `( ?8 k- S
6 O( R+ T+ R& z: M/ e; p 5. 添加地理标签
z0 s& ?* O$ w" L
# add pop-up text to each marker on the map
, ]6 U, N0 Q( \$ d! r/ _3 }+ y latitudes = list(data.Y)
6 Q' k) K7 L9 z M- e( |5 l
longitudes = list(data.X)
9 j3 b3 ~4 Z: a4 I8 ~
labels = list(data.Category)
$ n9 A+ T5 x/ y
5 i$ a& n5 P! _* f2 W; z9 M for lat, lng, label in zip(latitudes, longitudes, labels):
% n! w j/ m! x$ h% L( o
folium.Marker([lat, lng], popup=label).add_to(
san_map)
; P+ @$ D+ S! O9 M2 ?5 O# F
" W8 p0 m! T3 ~$ O' ?( n% ^# J # add incidents to map
7 l$ c/ P0 [& R5 ` U$ W) d+ V% L
san_map.add_child(incidents)
/ G: }# a' {7 F9 p* ]; w. p& F
9 R+ c$ t* P* N( m) g: A, M" {
6. 统计区域犯罪总数
9 A" v, S3 Z; ~3 v8 J from folium import plugins
# U$ f+ H# C$ H1 A
" D0 M! |9 w6 n6 \ # lets start again with a clean copy of the map of San Francisco
, i: C) F: ^) p: J7 x' z- F
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
' v) ?) Z$ y- L: H! K
9 c0 C b2 s. F7 |, \3 F4 m3 k% @ # instantiate a mark cluster object for the incidents in the dataframe
. o' A Z3 o3 o
incidents = plugins.MarkerCluster().add_to(san_map)
* f/ z1 }) r/ A& s+ m W/ n" N$ T q
# loop through the
dataframe and add each data point to the mark cluster
5 Y1 c" e4 \. b7 D% m
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
" `8 ]! c' U0 [' ^; f A3 \
folium.Marker(
0 N# a: w$ b+ V0 U
location=[lat, lng],
; Q0 R; s) d+ Q% R" z. U+ ] icon=None,
* w& e' U1 T. \. r popup=label,
, e" D# V) ]) n$ d) z ).add_to(incidents)
# Y$ c9 z g/ j6 |. {7 I4 D# v, y; n9 n
# add incidents to map
" ]( W5 I$ y* b. v6 a. ? ]% l9 J san_map.add_child(incidents)
4 f0 U6 H7 I# d. h, x% U
6 \! A* d% m. Y: `) a
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
; g: ?/ o# u! D& _0 ^, D( V( h
import json4 m1 I) L% Y$ A% ]
import requests
! A/ w' M% m6 P9 G/ b4 E/ m7 j( S& T3 | [! e* g
url = https://cocl.us/sanfran_geojson+ k" X+ r$ [- E. Y
san_geo = f{url}
2 G/ F" P g. ] @4 n- w' E! J- B* _) w# g san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
) n4 N" O7 c7 V: h0 ^ folium.GeoJson(
4 b4 }' P' g/ D& C( ~4 j$ ^& P san_geo,
; J7 I6 G4 ?6 e o style_function=lambda feature: {
( B8 \) Y% A- [: b: y5 [$ o& U fillColor: #ffff00,
% x! p/ b! u# N) m7 j7 K color: black,
. s. v5 L4 U# R; Z' P9 e$ O weight: 2,/ h9 N0 b" H, p4 E
dashArray: 5, 5
& `% H L9 F3 | }
9 x3 V2 R" p7 n% s# ~" Y E ).add_to(san_map), Z5 w* C+ k, f8 s* M! p S5 a
* o) M! N! i6 T( S #display map
! W7 Z" h9 Y; t" Y. b1 o7 W! G$ i' d san_map
" o8 N' w; {) P" x$ T * a! v# c; a1 c: G6 g5 e
8. 统计每个区域的犯罪事件数目
d. P+ d6 M! S' F3 S
# Count crime numbers in each
neighborhood0 S! l. T: Z; s/ P
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
) e4 i; g o0 ?0 {3 a7 ^ disdata.reset_index(inplace=True)
% ?+ D# }1 q3 Q9 ?
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
- k0 z- s6 z: Y% Q7 y
disdata
) {2 w0 `3 r! g) U6 b* ^
4 R% _' ]5 I5 ~% ~ 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
/ B3 V: ?' |8 v' K) p' a m = folium.Map(location=[37.77, -122.4], zoom_start=12)
: A: x/ P6 k q& `( C
folium.Choropleth(
4 y2 g9 e" a/ o/ C) {7 ` L
geo_data=san_geo,
! v: E# F* h3 N% k0 c data=disdata,
; Y' @* y8 f+ e$ }
columns=[Neighborhood,Count],
; u5 i7 P$ i! L& E x
key_on=feature.properties.DISTRICT,
5 a" ^% s* l& {% L k #fill_color=red,
G! q% u0 T$ P( @, T' f' A# k
fill_color=YlOrRd,
) v4 ?1 ^6 A4 r1 I, q
fill_opacity=0.7,
/ T! V5 ?) I: X" } line_opacity=0.2,
, U" C2 |& I; i/ h# g. l highlight=True,
/ G; }2 g, U& k1 e' |- F. W3 z& L
legend_name=Crime Counts in San Francisco
& l0 @0 I* _4 M* _3 C
).add_to(m)
Y% M& ^2 F* C m
# i1 x m! L4 k4 j* c* t
( r: g* f* v! t
! @$ a x$ o$ K 10. 创建热力图
, c6 f4 ]' t G) q2 d5 b% V
from folium.plugins import HeatMap
* D% k. I" y a7 D T* }# x8 @8 O" J4 B/ c1 A
# lets start again with a clean copy of the map of San Francisco8 z; T+ f0 G' @* @) |# b4 N
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
( `6 F. Z2 y+ ]/ [) t* ]% e0 i' Z6 u0 }6 L; ^3 `
# Convert data format: a, a; O& ~0 N+ V$ q/ r" p, v
heatdata = data[[Y,X]].values.tolist()
" Q8 x, y) K' r8 R2 k5 h/ n+ B: h$ o. e* b+ j6 Z' ~8 k
# add incidents to map" [, P: [& K- t6 ` f
HeatMap(heatdata).add_to(san_map)
0 f# z+ _8 h+ a, k" j4 s" `! p/ n8 ]: J. \, X% ^# O
san_map
; n5 @! q3 i! C
; v% k( t- m' I- v" T 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
8 ]0 _) R7 ~. j9 Y% n' d+ ~
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
9 a' V% q* {) D8 G" q2 H3 S
^/ l+ M7 h4 W
我的其他回答:
0 O# R1 s2 C; O7 v0 ^ ' p: ^; _) ?& r0 Y% d: g$ G
( f/ j; ^- a2 P. K x
: s- Y8 @5 G2 S+ G 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
1 x6 u s \, @; N: ^: \ 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
. k8 w; `" W5 G1 m7 s, r' r
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
3 b m- z- d& H+ A; f$ N5 A) u3 q
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
8 Z- C/ }4 e) Z 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
P- q+ p ~; f# d! T5 t: v1 _