& z+ o: C# _% y4 ^) J! B 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
+ ^& L7 H2 S4 s- p9 S
4 c$ k4 D* j+ G- `, k+ {
使用方法很简单,操作如下:
导入包,创建一副世界地图
7 p: o) R7 H6 m6 s/ r& r import folium% `3 h4 x" N6 Q2 r% ?5 K* ~3 c
import pandas as pd
. j1 [/ r E1 g, [+ y) R/ X9 z1 }# O1 ]: F! k
# define the world map
3 I. L |) Z2 i: I7 v world_map = folium.Map(): D& r6 Z' K1 J7 x$ W3 M6 l( u
: f& @% [6 U5 H* F* _ v" g5 A # display world map
- B1 Y7 g! I1 c- E/ d5 V1 K world_map
# B1 j5 p3 r2 m4 H1 `* O- Z" z7 N ^4 m" u. @
. T; r/ s1 D& ~1 D+ ?2 z1 [% I 2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
7 w3 G6 \3 M+ \: y* h
# San Francisco latitude and longitude values5 \7 Q g3 h2 L0 j% h- E) l
latitude = 37.77
# P5 C$ B% `2 ^6 C8 {2 u longitude = -122.42. b! w) e7 @8 x3 N% X3 \) n6 }
+ Y* n+ }5 M* t i( o2 R+ k' G W # Create map and display it
/ A3 }( x/ g- X san_map = folium.Map(location=[latitude, longitude], zoom_start=12)1 m4 @ j8 ?* M5 i; Z; `
/ W% q; F8 s7 Q1 P' P # Display the map of San Francisco. G( m5 ~6 [4 f7 ^+ L! e# W3 V
san_map
: [! b' D6 f6 k% [1 V. k / R- _9 d* c' K
更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
3 D2 e; ?( `0 c% D # Create map and display it
7 j) F" f! I! C* K& H/ u san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
( e5 c9 f2 l& Z" Z3 \( U ; R# o; [4 V f7 v
3. 读取数据集(旧金山犯罪数据集)
) t- _ j8 m' ~1 W
# Read Dataset0 x/ A- I. A# b
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)2 A) {3 ?, T/ Q, B- q* O" N! g6 o4 M
cdata.head()
; Z. o# t1 [% v3 R/ E $ s/ ]" |& r! N& Q$ R
4. 在地图上显示前200条犯罪数据
3 {% q# I- I! _7 s
# get the first 200 crimes in the cdata
4 N0 V* G! O/ s7 y' ~ limit = 200
3 W1 f1 }. W* w% ~8 J: b. f4 w, T data = cdata.
iloc[0:limit, :]
% j/ C( F8 P% [. W" o) V
) u+ \* h' v1 X- a # Instantiate a feature group for the incidents in the dataframe
$ W4 m( k4 \8 m1 K2 ~; r L6 y
incidents = folium.map.FeatureGroup()
8 X7 [! X1 U6 M: F" A& K
( q; x" O0 t1 { i9 \2 \
# Loop through the 200 crimes and add each to the incidents feature group
8 a$ o0 d' [% X7 U/ o
for lat, lng, in zip(cdata.Y, data.X):
. ]7 v4 b z( G+ Y& x" v5 \
incidents.add_child(
" x2 g; n* K) Y: Q* D6 c8 O4 C folium.CircleMarker(
" I c4 s9 [5 M [lat, lng],
8 {& ^( d2 {5 V8 N/ A1 _
radius=7, # define how big you want the circle markers to be
8 l; k0 C$ n/ n8 h
color=yellow,
% ]- w3 e$ m! M8 c
fill=True,
" \# X! M, g0 p7 |$ C% [ fill_color=red,
) x, v/ ^, F- v' O8 r fill_opacity=0.4
3 X0 ^5 D3 e0 |* u0 g4 w# \9 v* ^ )
9 u4 x% ^* l( B9 b- @8 g. r
)
$ A" w) q3 q* D% @2 X1 z
G) O! v6 i* Q- l # Add incidents to map
5 j" }: \8 r0 ?, n% W/ P0 K; @
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
0 d6 G* Z( D; w san_
map.add_child(incidents)
0 A: j' s+ M4 J( A
( o6 P! }6 ^" \% E4 |) s* ? 5. 添加地理标签
9 A4 M6 |# h% W0 q5 y
# add pop-up text to each marker on the map
2 a$ X( |3 x. _: B, W: a' r( |) E
latitudes = list(data.Y)
& Z, ^8 [% c5 M! o
longitudes = list(data.X)
$ f% \1 e( o5 ?: S labels = list(data.Category)
& N6 ~0 g2 S* k7 P1 L- O* d/ v/ b2 T2 _6 R
for lat, lng, label in zip(latitudes, longitudes, labels):
/ }, c+ Q7 ]5 ^% g1 b L( ~9 A3 V folium.Marker([lat, lng], popup=label).add_to(
san_map)
& R' _% a% p- J, Z8 ~+ ^; @
* U7 ]+ h; E. P! s* y f
# add incidents to map
; j1 G b T3 X) ]$ Y
san_map.add_child(incidents)
& f. Z; ` q( ~7 e & X( M% O4 D7 V! G1 U3 T
6. 统计区域犯罪总数
7 [ J; Z) Y5 H9 {% a0 P0 i' Q
from folium import plugins
( t- R; f5 F' N: X7 h1 |; |+ U/ d( y4 ]8 d9 N+ q$ _
# lets start again with a clean copy of the map of San Francisco
9 d4 ~/ b) |; c( F: a: ?
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
+ L) H% Q4 O& @8 N; n+ m- |3 N
9 M+ x- I7 h8 i! A7 F8 d
# instantiate a mark cluster object for the incidents in the dataframe
" G4 J( Z9 _$ S
incidents = plugins.MarkerCluster().add_to(san_map)
( r3 }4 L5 |# l+ k- i
0 P1 Q) L/ f$ ]; w& { # loop through the
dataframe and add each data point to the mark cluster
/ i! `3 u$ J' G: [
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
8 a2 {7 e1 f5 o6 x3 K2 g
folium.Marker(
/ D6 {$ g& h9 U K2 |' D% X; @ location=[lat, lng],
9 D' K% Y- X( C, Q& `, ] icon=None,
+ @) k2 \6 m+ v7 a7 R
popup=label,
2 T9 M$ [7 u- l; Y
).add_to(incidents)
0 g8 p0 k8 A6 F K) A
6 Q* z, F4 F! I! X- Y
# add incidents to map
% F6 B$ g; ^! A v3 L& i5 F
san_map.add_child(incidents)
9 k$ ^$ {' ~% q! `4 }* q/ C4 H
7 Q! O! s9 [# J2 ?5 B 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
* d3 ~; v4 l( O& h% v( {
import json6 \0 h, j( c* d; v+ _
import requests$ o7 G" B9 L+ f1 g* O( e; C! R
5 f* u, R% f1 f) @3 `: _! m$ v, K url = https://cocl.us/sanfran_geojson* P; r7 F# ^* c, p ]5 [4 @6 V+ K
san_geo = f{url}' N2 C/ B1 u- g( V$ t2 J1 c0 g0 [
san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
) W2 D* k8 _& _! b, F" [ folium.GeoJson(- O1 _3 h9 |5 f/ F! z
san_geo," i( M1 S0 E b" {- ?
style_function=lambda feature: {4 v' o4 p+ @: F8 `7 `0 g
fillColor: #ffff00,
7 d1 F* {, t5 a) Q+ O- \ color: black,( q, [5 w, T! [' l: G
weight: 2,
$ ]; w: B, W. w6 k- {- L, q+ R dashArray: 5, 5
' i' S. m: Y' I6 s1 S K }
2 `4 O$ p- W9 m ).add_to(san_map)- n# k2 r. |% K# v9 U3 B
+ t4 Y" _" y8 K) v8 B5 F
#display map
( } M7 H3 K' u2 `7 B san_map
# r# `& ? k/ E, V
! s' I% H A7 }( R 8. 统计每个区域的犯罪事件数目
( \6 s. T) H/ L% o # Count crime numbers in each
neighborhood' s' U5 o8 @9 ^9 C
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
m- |6 R+ P! i7 {" G disdata.reset_index(inplace=True)
) k7 {+ J1 [2 G9 @! C9 o) w0 R$ R
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
2 T4 C1 l `6 W) n$ N" h/ D( p disdata
/ Z1 I* C$ {. p' p: T
8 ~0 k# X5 A) {: V 9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
5 E3 N' ~: N0 g1 g3 F ~* S
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
5 Y/ ^; @) S1 o folium.Choropleth(
( t$ U# i4 r' C% H3 b: I* g- u geo_data=san_geo,
2 o$ ^) [3 N; a, S data=disdata,
! o A G! T9 u9 O5 H, @7 V% H( I# m columns=[Neighborhood,Count],
$ L2 k# H; r" u1 P: Z t! J
key_on=feature.properties.DISTRICT,
$ c3 Z6 t+ ]& h: @! G. |2 R0 I; ^ #fill_color=red,
8 ~) R! O, R* w9 c* ]" i
fill_color=YlOrRd,
# ^7 B' r- y( | j+ b6 E& R& j6 ?, c+ M
fill_opacity=0.7,
6 ]% V, c! j6 d' S, q0 C line_opacity=0.2,
" ?( N5 p8 c6 w) D8 {1 b
highlight=True,
$ @9 O0 V3 ?1 G* X( y* \. k0 ] legend_name=Crime Counts in San Francisco
: \, [! N5 i1 Z5 |! x- q
).add_to(m)
1 S& d6 }- L4 V( o3 L& u4 ?! K+ L
m
& R+ T+ y, A$ \5 c0 Y
# O. Y, m+ I/ v$ h& O G& N% T! x
# e. m6 h9 N4 C
10. 创建热力图
: n7 N1 \5 A, H3 t; V* p- d
from folium.plugins import HeatMap) A1 W$ n+ |, v& R: k
. @* j& I: A% Q" g7 W, P # lets start again with a clean copy of the map of San Francisco
: J1 E$ A7 U2 h3 A; \7 j- [ san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)7 O9 @2 w; q* d# K2 q8 k2 G4 s7 `
2 _$ k! a4 j9 q/ W
# Convert data format
5 X4 @/ _; }# ]) ~+ U8 | heatdata = data[[Y,X]].values.tolist()- h) ?& q8 W3 r$ s; a2 ]4 R
- D, B6 r0 k/ @: G6 B& i2 s
# add incidents to map
5 r! [& u; }. z$ P$ u2 \ HeatMap(heatdata).add_to(san_map)
6 o. V9 @: z% W; u* |' F* n7 S6 Z% w( B$ [: `6 j& p! W
san_map
+ Y Q) k! }9 N ! f e; r" b6 n# {# h. w: g9 E
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
1 |" E6 o. c! n7 W+ n. ]( K" ^ 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
8 o: b. x& F p% Z0 k
8 S: V3 Z- j: ]0 N 我的其他回答:
" q2 S9 Y% f; n9 d _
, ]2 {5 A7 h! e. J5 e 2 X3 m$ y% j$ O4 o$ y% k1 ~& G" N m
& G; @% ]7 T; _9 H0 Q+ A 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
Q1 N" F+ E/ C9 G 1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
" y7 P) c$ t0 f, c+ u 2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
2 M' n3 v9 S. X8 u% G 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
- ]/ f/ g8 e- \" T 最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
" ]. H2 m# y: l" _' m' y7 M