x, D" Y% d- D W& ?3 ?; |! {9 a
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
( |& n, ?2 }( d9 X# W. w
8 I$ p4 q5 b' A8 L% L 使用方法很简单,操作如下:
导入包,创建一副世界地图
0 R# _" A6 k; P- a. y. K import folium
6 g7 ~' [) r; |9 K, C& Z! e* k import pandas as pd+ z9 a5 Q+ G1 Z( Y! ]1 e2 h
. Z+ r3 B( e1 `* {1 Z6 ^; D! p) E' U/ i+ X
# define the world map
: D8 R: F* t1 w" \! ? world_map = folium.Map()
+ G2 |4 u+ V3 u- d- {% ]$ w/ o0 q* v# A9 F+ N4 f$ J/ }
# display world map
% K5 J. {9 [2 r% Y6 @2 z- b world_map
# E! u" s3 }/ T; Z 6 @1 }* C! F5 M8 N/ ~' x; a8 q
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
$ P/ u! q' S9 }8 M1 K/ t1 a- q5 } # San Francisco latitude and longitude values- W& C+ G1 o+ x) @2 h) ]- n% t
latitude = 37.77
8 X4 b' h$ \# O$ l longitude = -122.42
+ D; k; K$ ?& s4 I8 Z
, F% U! Z# ?7 A4 g9 G; y # Create map and display it
$ `- `7 n8 E# M. y san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
7 v5 {# c8 X+ P& l& K8 a9 R
$ Y) A- P( m* [' }( r$ _* W. k # Display the map of San Francisco
[8 z5 R ^/ V' X2 ~ san_map
& y( Q! B& ~/ S7 j1 @" z4 z- b" Y2 h
( y4 {+ ~$ `, W* g 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
5 W& P, T& Q* t, Y4 `& Y # Create map and display it# j, X$ d- w& N
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
. C W; @8 S# n
0 i/ U9 e: ^+ h7 K
3. 读取数据集(旧金山犯罪数据集)
5 @7 i2 J, ^' C3 B& f. Y0 t# q& {
# Read Dataset f) H `* b; {! N
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)+ {0 |6 r: D5 g8 |4 n0 j- b
cdata.head()
" j/ I) }8 {0 E, [
* {6 u! Q0 ?/ G/ D4 a& | 4. 在地图上显示前200条犯罪数据
8 q& U( f$ M l$ ] # get the first 200 crimes in the cdata
1 y! Z" r1 w9 Y
limit = 200
: Z% \) h& p# K3 \
data = cdata.
iloc[0:limit, :]
. N% I; y6 K; Y6 t' x! \; g3 }
" J8 \3 y" ]3 w0 ?6 Z( K/ m' q! |
# Instantiate a feature group for the incidents in the dataframe
8 p5 I0 q( y( `: Q5 z0 o% W incidents = folium.map.FeatureGroup()
" J5 W' v) T+ Z( m" ?2 {4 e2 `4 v4 T
# Loop through the 200 crimes and add each to the incidents feature group
- S8 q' p: L( p3 f; \ for lat, lng, in zip(cdata.Y, data.X):
- D5 |9 a1 |# \% k; g# T" R incidents.add_child(
! x. W- e- o; c- B9 | folium.CircleMarker(
* c( ~. S9 l( t+ a& D/ Y [lat, lng],
! L/ A+ ~3 P& Z! V- w* T
radius=7, # define how big you want the circle markers to be
?3 A- u5 G6 B: I, V color=yellow,
* ?) a2 h4 J4 i) |3 ^7 j4 K
fill=True,
' }3 y, A& B: ~. [$ a- x4 u1 w1 L fill_color=red,
7 U7 O1 Q1 `' e L, E
fill_opacity=0.4
; W0 d; o$ X" n' s
)
* @, j- b7 [9 k+ I, T" |* t3 S )
9 m6 P/ y' k0 S) B' ~% e
" S! E5 I$ j9 F, B: t4 v- ?
# Add incidents to map
; H4 M* J) ~' S% |! ]' ]6 E: ^ san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
3 {; {% F5 C1 J) O U san_
map.add_child(incidents)
% `, X0 O8 F4 w. H8 j9 a
1 o: ]1 H$ ^8 [# s1 | y 5. 添加地理标签
# |" D8 X8 _8 _0 v8 N8 C # add pop-up text to each marker on the map
4 S& z, W; B8 W2 z& z# l5 v latitudes = list(data.Y)
% v3 Y+ s0 l2 V* ^( C
longitudes = list(data.X)
( }" j5 U G1 C
labels = list(data.Category)
" H* T$ v. G; c8 X2 f ` [% U$ \1 S8 @* f! z6 S
for lat, lng, label in zip(latitudes, longitudes, labels):
" L7 B# ~& ?) O, V: X$ R! D folium.Marker([lat, lng], popup=label).add_to(
san_map)
" A: m' g0 g! P
$ |( e& @8 o% f; y f # add incidents to map
: X3 g' T$ L4 @, f% K6 R
san_map.add_child(incidents)
# O! U& K3 Z" P+ B$ @* Z3 \
! J. V O6 t; N5 W- u* |5 O 6. 统计区域犯罪总数
5 P: g" w1 s' f. @/ G5 y
from folium import plugins
1 I3 ?# o4 C3 |, @$ b. S
6 C+ J3 s b% p" o# n% I
# lets start again with a clean copy of the map of San Francisco
5 N7 ^' V" p$ X R% q: d- y, Q0 N san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
% s; u5 [! L P2 B$ ~7 C/ t
/ |7 r( z" j# L0 s- w' E) y # instantiate a mark cluster object for the incidents in the dataframe
/ T* q S- ?! I( o7 h0 Z% k incidents = plugins.MarkerCluster().add_to(san_map)
7 S7 t3 @9 D& [, x5 [& t1 ]3 Z; b2 C( I9 @# m2 y* a8 W
# loop through the
dataframe and add each data point to the mark cluster
5 ]* ]4 `, S- o5 t: h1 o
for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
) h4 ?) s3 W n( y, p
folium.Marker(
" L: T" d# \5 q# n7 D
location=[lat, lng],
5 V( F0 c" W6 D/ c+ f" {3 K5 S% l, T
icon=None,
# q8 i& m7 T4 X popup=label,
0 \% j' D, _, y$ S, a/ M ).add_to(incidents)
8 M8 k' P. K/ a, K1 l7 l1 x$ Z3 O, L/ S6 v
# add incidents to map
0 Q& j6 |+ U4 U6 w/ p5 u san_map.add_child(incidents)
5 }: w+ l' M8 }* ?. o
- L* U* g0 U" A9 I 7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
% |( K/ h8 m/ w* C5 w" K! N import json2 V J% n# J+ f5 O8 g. L3 l
import requests
9 m- _; Z; N* N; {9 E; m+ P- \ j5 `( I, U/ H
url = https://cocl.us/sanfran_geojson
# \5 q5 d: N/ D" d san_geo = f{url}
2 G8 X/ }8 s$ J1 G: ] san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)
- L0 r( `) z. O4 h folium.GeoJson(
2 R/ j9 U7 R$ x j6 Z san_geo,; `3 J5 E* J! Y* k& ` B' p% l
style_function=lambda feature: {7 m" q- m/ T0 C
fillColor: #ffff00,
. H- e! G4 B' r; ` color: black,
# M' j7 M: e2 ^2 q# k weight: 2,6 r' l& x7 h- C7 C/ X( F
dashArray: 5, 5
) Q, M; e- V9 |, @2 s }
! p) L1 p, @, d. \ h ).add_to(san_map)" L9 X- r# N) R) I4 K' K
" }* X& N$ [* I7 K- V( @2 U8 H
#display map% F% v7 |- [9 |
san_map
7 T4 y; P" ^6 |0 K1 i" H4 N
( o+ x( a& p+ q+ \0 ~) A, ^: u. J
8. 统计每个区域的犯罪事件数目
1 C! X0 ?* J- X4 E: S. j* @$ e7 n
# Count crime numbers in each
neighborhood
3 r2 q# }1 Z6 l. S$ E disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
' k, m/ [! T# a$ ]5 f
disdata.reset_index(inplace=True)
1 G; R: F9 `& v3 w* F3 A4 |+ B, f
disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
% a6 s: U2 R( \* p8 Y9 c
disdata
2 K7 k$ U p) v" k; E O. X" K
/ K) J- A* ~8 V0 B q, ^' M
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
Q& e: S* M: Q" \# @4 ?# _
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
1 z2 |6 O: U+ D' q" n# r
folium.Choropleth(
/ a! g2 Q; v/ [. c8 n geo_data=san_geo,
6 `, }1 O& a- R data=disdata,
$ D$ _( o, K+ M% t8 W/ _( D$ T columns=[Neighborhood,Count],
- Q6 e. s% B o! K8 Q& W
key_on=feature.properties.DISTRICT,
& i5 H& y& A2 q& P. ^( `+ @. M #fill_color=red,
! E2 Z8 \" U$ J. \( ~1 Y. Y fill_color=YlOrRd,
/ O: t1 L* q. R! V- r2 ~ fill_opacity=0.7,
4 I" \/ j" U1 t
line_opacity=0.2,
% v7 X% z+ D+ K8 @
highlight=True,
7 k; r" A! Y/ z; w k! N legend_name=Crime Counts in San Francisco
7 Z) w. E$ K8 J1 ^6 S ).add_to(m)
; b; m! t6 D- `& n' f, ?6 W m
6 p" ~: {* f3 }' }
$ E% X3 H3 ?, k! S2 H" E
) N# ]& i( c6 I9 }1 \$ S9 U9 c% y6 d
10. 创建热力图
& z# t# g* f8 G8 j from folium.plugins import HeatMap
6 D# ` S" ^& K5 o# Q; m1 a
& R5 L4 c7 Y. m; j0 l # lets start again with a clean copy of the map of San Francisco
8 b- A. s* ~4 ^# e2 s: R san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
1 c; Z1 W8 z9 p1 G+ X. m* Z b
7 v: r4 w; T5 S; U* Z% ] # Convert data format
1 y* }; K P f, e heatdata = data[[Y,X]].values.tolist()% r; _1 O3 b6 ~( N" q, |4 C7 Y
! U0 o3 r' n; x: }2 H9 V# A9 K # add incidents to map
, S" O) K+ E8 w B1 @ HeatMap(heatdata).add_to(san_map)2 Y. U6 D- u: Z% h2 P
8 K: F, o: u; @7 K" |& V; G+ U0 q san_map
) N$ s8 i5 p7 V ' }, T0 M' F# q
最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
# E1 {5 m. V' K8 P# a
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
) ?7 D; p. M# \* h; K; d' t' X
( k& |0 f f; c6 L* k9 W! a
我的其他回答:
; `; L9 z& G% ?/ j/ J, g$ k# X
7 \7 @7 f0 E2 {5 p- c3 @% Z1 C5 @ 3 ~3 |% f% c6 V. N( U
& h$ G! O8 h, |: p9 b 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
! Z; }) \ }4 ^/ o
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
4 E+ M3 t8 \# U6 \/ ]- }/ e. m* z$ Z
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
1 x2 T: i5 M7 m: ^4 F+ L/ U; i
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
8 N; y* |7 f/ G2 T4 j
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
' I- b+ T3 E" \* o" w/ O