2 ~+ E9 u& P% j
推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
" i+ ?3 P! h0 U/ o. U; T; e9 G
+ S6 `& w" S9 P7 H2 y/ m% U
使用方法很简单,操作如下:
导入包,创建一副世界地图1 Q2 f }) _, X" k& _' A8 D- z# K
import folium- _0 x% X4 }7 o) S; @8 O: M3 f
import pandas as pd3 F9 S* D u0 J9 O+ L
" G6 s5 Z0 i! C
# define the world map( P* t8 Y# g. N6 D z1 l3 W
world_map = folium.Map()9 t* Q2 K q- u/ Y
9 N! R$ M1 c+ P X/ }0 Y # display world map
' a1 d2 o$ v, l7 p% J m1 Z( h world_map
, x" T( y$ K! t% U! U: q+ T ! a ?5 ~4 ?8 v
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
8 k1 v6 n! b1 W6 C# y # San Francisco latitude and longitude values' u: C' }; s$ ~9 n2 d( P
latitude = 37.77( l Y4 E4 c- R% f
longitude = -122.42
0 C# w: h, S0 ^; H1 u& `' `6 E. W3 s% `4 e- `( e
# Create map and display it8 O1 e( M- s& o; Q L
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
/ `+ c: h" \: \! N" C
4 O* K% t8 M# @: I6 H% ~ # Display the map of San Francisco
6 K) v- M: J5 C6 C! r% j4 i san_map
9 Z7 z% e" E: @' \ u) p7 Y( \
4 N( g1 z' Y! U$ s1 e 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
5 M; Q; Q0 T& E # Create map and display it- v/ x, n, y" T3 V
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
( v# ?* q0 `! {( r: r+ W
[1 O: Y/ M* B$ k! F9 T; o 3. 读取数据集(旧金山犯罪数据集)
5 q$ ^+ r6 j# k/ ~ N8 ` # Read Dataset7 K4 [) V# W% i% |. g7 I
cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)" {: `' @- V( G) \
cdata.head()
$ @2 e* o+ S* h* [, {' C" ^
& g. N) @: Y* i9 W3 i 4. 在地图上显示前200条犯罪数据
! K, M8 X( J+ ?8 |3 K- i/ R7 I( a6 s
# get the first 200 crimes in the cdata
9 y: [4 q) ?! ^3 ]% W: k1 J8 E
limit = 200
, D' @; Y. G& s9 W7 f
data = cdata.
iloc[0:limit, :]
5 w7 o9 ]" G) d$ @) N$ w" d8 _, C: o9 G: K
# Instantiate a feature group for the incidents in the dataframe
( x* B, f. y# }; D& A* a J) V incidents = folium.map.FeatureGroup()
) G; U2 j! D, ~. W* n# ]; E* n9 m2 J- ^% l
# Loop through the 200 crimes and add each to the incidents feature group
6 h' S( |/ p/ \9 E$ G
for lat, lng, in zip(cdata.Y, data.X):
7 A" _2 o+ Z, W& t7 |) f+ }& j incidents.add_child(
( I n! F1 H* y( f
folium.CircleMarker(
* o$ \, R+ l* M' {: G& N/ r
[lat, lng],
; [' l& n+ N8 p, i- M% j
radius=7, # define how big you want the circle markers to be
* C2 L! M! K$ V* \. S7 _1 p
color=yellow,
% I Y/ ]( c( ]' ] s# F3 X) A. e fill=True,
% ]+ _5 z* L, W0 h6 Q fill_color=red,
# D1 ^" @, N! j- P" `
fill_opacity=0.4
' F- V, _+ E4 U, k Z! ]
)
, r$ n$ K, t3 z )
7 ^/ o. N, s- G+ B6 @4 D `% J9 g+ H) ~1 u
# Add incidents to map
+ S6 Y! v' U$ D e! _' _% [+ N san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
" I/ H& `- C" s U$ P1 U- ` M san_
map.add_child(incidents)
8 v- J7 M0 M% q0 j7 ?* h- L6 G
* C. E& F( N" }6 Y! t0 C0 ?, f) l 5. 添加地理标签
' Z- z I' a1 a. L # add pop-up text to each marker on the map
" L- u8 ?+ G, ] y/ B latitudes = list(data.Y)
8 p' G6 V* \; U6 U! W$ G" }
longitudes = list(data.X)
9 q$ Q8 A3 d$ a7 K0 W' Z labels = list(data.Category)
* k9 ?& I' k! C5 X) d+ z7 i
( ^( Z$ T* M+ N6 P4 a* K- l0 \ for lat, lng, label in zip(latitudes, longitudes, labels):
' f- O7 Z) n- N2 T6 M1 _' Q+ h; j
folium.Marker([lat, lng], popup=label).add_to(
san_map)
. A( \) C5 t: X$ D! s( i4 i' M/ V, y5 ~4 ^* h9 I+ N
# add incidents to map
1 p) d9 ^+ ?9 ?& u san_map.add_child(incidents)
/ M+ e* n, M4 Z; E) \9 f
: k, T9 G. y- T- ]/ M$ }9 \7 k
6. 统计区域犯罪总数
0 D& R0 q5 i8 v7 c0 r C from folium import plugins
9 g7 |9 l6 d; k6 D D* |' u
; H2 E0 ~6 }+ Z; v
# lets start again with a clean copy of the map of San Francisco
/ v3 j& e9 k% S7 E7 W- N, ` san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
D+ A% T! V( A2 W, [# L$ V7 Y
- [$ Q- h" q3 j+ s5 A' B
# instantiate a mark cluster object for the incidents in the dataframe
" H O0 Y$ {" f/ D2 g# D
incidents = plugins.MarkerCluster().add_to(san_map)
4 g& _, y& s' ~* W: Y* H) \
/ l: H/ i9 u& U ^ # loop through the
dataframe and add each data point to the mark cluster
* i: H( p% x2 n9 i* I for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
9 h/ ~* z/ z8 r5 O r5 Y4 Q7 h folium.Marker(
7 r# @( _% b! [: O+ s. l! h
location=[lat, lng],
3 N0 h* k3 p# i% @ icon=None,
2 E9 y2 O1 q! u9 B/ H. P
popup=label,
# b4 r$ W. ?; Y ).add_to(incidents)
1 @5 @) q4 Z I
1 m% y* c* ]. F( D& m
# add incidents to map
) k& R, f3 a+ p; [3 n; N
san_map.add_child(incidents)
) k6 v+ I9 Z& z8 e
e }. i5 q: A6 _( H
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
8 O; i. P1 X( h import json
' J! H1 s' x, Z import requests; e6 z# a3 ~! }" _% O! r
|$ e0 F$ ]0 n ?8 F
url = https://cocl.us/sanfran_geojson
2 X; v6 x+ R; l" a: {. n+ c* { san_geo = f{url}
4 n: P* A! V$ U: M) \( U san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)2 A, s. x2 \4 }$ T, B6 K
folium.GeoJson(
2 l1 T9 Q1 _: _6 D! J san_geo,* x' ]; U! o5 |: x0 [% s
style_function=lambda feature: {: N% b2 ?0 ~9 _2 [9 [
fillColor: #ffff00,
2 e8 c. S# }, i4 @% g color: black,
. w% C, R) G! W5 c" Z) ~ weight: 2,
) w- z* W" \ ^5 N* e3 A dashArray: 5, 5
- J- Q% u/ `* n# _7 c }+ l4 M4 ?6 Z/ M3 x
).add_to(san_map)1 Y) V! X6 e L! `
h# _! f4 F4 q+ ^9 W b
#display map
/ d3 _$ C3 r/ X& g) s san_map
2 u/ T; l' j5 f4 H3 V3 t
, n) B- ?# ?- m: h' X) A
8. 统计每个区域的犯罪事件数目
" I- K2 \3 q5 I+ Q
# Count crime numbers in each
neighborhood" d/ n8 ?" K' d. r. A! g% p: A
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
% ]! ~9 z$ I1 U+ l A5 v
disdata.reset_index(inplace=True)
7 e, z) U/ u/ M2 d7 Z) x disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
( k: }, s( F" A; D; U/ y7 N2 h, c
disdata
( S" R1 g) L, O2 I" k. g( Y( y8 ] 7 v7 k" _. ]; T% A% x7 n, T/ N0 S% }% j
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
! ^+ Z" o- Z& p$ g$ k$ N
m = folium.Map(location=[37.77, -122.4], zoom_start=12)
4 `6 m3 N. v- C7 w% I
folium.Choropleth(
' c( a5 ~# l/ X7 S2 v1 {! u* A
geo_data=san_geo,
- |% U3 w" k( H) r2 O data=disdata,
# s) v0 k9 F4 w
columns=[Neighborhood,Count],
- o3 \3 c8 M0 S8 V
key_on=feature.properties.DISTRICT,
: q* O9 J% P$ H* \4 p
#fill_color=red,
8 s( A# {% J _5 Y: u& e* y fill_color=YlOrRd,
8 @ b3 P0 q0 B. t
fill_opacity=0.7,
7 c3 ^1 \3 T \0 f. ^
line_opacity=0.2,
: \+ q) M' x8 ^" f highlight=True,
) G* U: e, v5 c4 L$ p: | legend_name=Crime Counts in San Francisco
* ]; N u" [5 o8 a' I4 |& ]0 B* y
).add_to(m)
' [5 }, K7 a1 g1 ?$ x# ^
m
4 n( J3 c6 r M3 Y7 q, f. L
' D' ]$ m- ?" r3 b0 a0 S8 U2 b% Y9 _
( e: T+ Q3 W2 Q& A; u& B9 o; O! A 10. 创建热力图
0 X8 x5 E5 ?$ K8 b7 B4 R1 ^
from folium.plugins import HeatMap
) P1 H7 B1 i' m" G. B: K7 A
! q! ^# ?) [ S # lets start again with a clean copy of the map of San Francisco. Q7 j1 y5 J5 F% m3 H% u! K( O
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
1 T4 r1 g+ I& q2 {1 |, w
! o/ {) G3 n, S # Convert data format
. Z0 r. e+ ]- J7 Y* I heatdata = data[[Y,X]].values.tolist()
) t; i- ^1 H- x6 x# `4 n- K# L: }- V
# add incidents to map
. O! R, o- r; A$ A$ [6 J HeatMap(heatdata).add_to(san_map)* x" j+ O5 \* _ A$ x
1 B3 ? A9 T: r* g+ ?
san_map
: Y& ]" X/ A* ` P
1 ~- J; G0 v# z; t% @: Z* [ 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
6 }. q) M* c2 c2 ^+ U 实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
" p: F: V' ?' R+ }$ T" Q . N* F; h$ M1 O+ q% D- w8 p
我的其他回答:
- F1 I3 G, b: \. i+ g' L 8 x- s" Y. G4 H) l% ^# I8 x2 w7 b$ _
3 ^# Y1 {; g4 X& Z$ g6 {! F
/ |0 o Z3 _9 @# i 最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
% e. N7 g# R5 d6 A9 b; M
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
7 }6 a3 n: L$ Z% X/ A
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
% D& {" b7 N/ D1 O 给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
* U8 U4 \4 \ \, U" C8 Q+ i
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
; G6 t2 r+ x8 Z* G8 X) @/ r% M! \