4 z4 A+ w* n; W1 E 推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里。
( s% y$ [6 W' D) s $ T+ |3 Z; }# n4 b! C) f
使用方法很简单,操作如下:
导入包,创建一副世界地图( R2 Q4 a+ E+ F: W$ G. f
import folium( h9 e* `- a9 l6 h5 H3 J
import pandas as pd
; G ^& T! X h* F4 C: {( O6 e4 x, Z. j+ l0 B
# define the world map. `5 p. N3 S0 c- F. E1 d
world_map = folium.Map()/ o: ~2 ~5 H/ n! v1 }
9 P# f: P2 P0 A0 ]4 s* s # display world map3 W! c- R! J' x* B+ N; _
world_map
: p6 O5 ?' ]5 ^
3 \/ r! a8 Z% P6 V- o! x. y
2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。
2 Z' l5 r# ?! |) @4 Z* j$ \0 m; e # San Francisco latitude and longitude values
( J! p" A5 W: } C. ?/ D! b& L latitude = 37.77
1 l' P4 l4 V* H' {" u" s longitude = -122.42
/ |) I/ x4 }2 R' D# a- ~4 G
6 R) e8 T# K* Z # Create map and display it {8 p( ?) g8 x, {* G" R
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)& [ \" d3 ^' ]9 L- T
6 E! [; o8 r2 X: R # Display the map of San Francisco
: z2 l4 ]8 j5 x3 b3 D7 i6 z san_map
: K# b6 F% u" _- @! N# @
+ b3 H) x6 T1 S$ ]4 i% e& t 更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。
: Z" {, O4 {2 S( s. ` # Create map and display it1 c' I1 X) ]1 S1 G5 h* N
san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
" l; V, [, h8 P. W, b& y V6 E
% y# ?* t" A+ U, G* ~, _6 f! ^; w8 `3 A
3. 读取数据集(旧金山犯罪数据集)
, g5 r2 L6 d- L) a # Read Dataset
, d/ L9 \, F/ e# }' M8 ?; i. J cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset)
" |' B+ _, v/ D1 H6 k# C cdata.head()
8 l8 H. e% E+ R
4 T! m( E" F' X7 p7 R 4. 在地图上显示前200条犯罪数据
$ N) F4 _3 m4 F2 G* Q* c9 K
# get the first 200 crimes in the cdata
+ `. V& \8 N+ @% a2 k( k8 j9 H! \ limit = 200
2 b5 N) A# B( V# ~: l
data = cdata.
iloc[0:limit, :]
' [$ _& e3 k3 h2 D. d9 S2 h
* `- Z8 {" z, B. z& @% N
# Instantiate a feature group for the incidents in the dataframe
# @! {1 o) Y6 |1 Q$ \9 v incidents = folium.map.FeatureGroup()
$ V2 I2 z1 \, D( W1 ?' D# i2 |5 A+ |7 U7 K f7 a
# Loop through the 200 crimes and add each to the incidents feature group
: o t& q, \( |( E- }/ R for lat, lng, in zip(cdata.Y, data.X):
" V% p2 A5 N' a4 t1 r! ~6 R incidents.add_child(
1 P p8 i$ n i: z. w: `6 C* Q' j
folium.CircleMarker(
1 c2 Y+ q# W7 x% s6 ~3 X [lat, lng],
. D* Q: l9 [* n/ F$ Q radius=7, # define how big you want the circle markers to be
5 r/ Q5 s3 c# m) s- T/ x) z: k
color=yellow,
3 e- T, L/ h9 j- r0 O& I# N fill=True,
; _/ _+ q3 p! i) i/ Q0 C2 W fill_color=red,
1 L' \* e {3 A! P8 w5 q3 N7 j J
fill_opacity=0.4
; D R- r* x' L% A3 V" |5 B2 ~ )
1 g0 q+ B! L; P+ W- R& H( j
)
# c) \' T. E* n- T
. l$ w1 l1 d2 P6 w% Y% z" F0 P # Add incidents to map
/ Q' ?: [ \! N$ f! g
san_map = folium.Map(location=[latitude, longitude], zoom_start=12)
) O9 a% t5 U6 H* Z san_
map.add_child(incidents)
. u6 M: S$ i0 {7 |$ M/ k/ B
1 m) w& g* m; H, Q2 ]; H0 \7 t+ E 5. 添加地理标签
4 u; c9 F! n# g# j3 L
# add pop-up text to each marker on the map
5 p8 m( Y! M- y$ c
latitudes = list(data.Y)
* i- y& `# X. z- u0 J. r
longitudes = list(data.X)
$ a$ m) {+ |4 d- A( n" v6 l* K labels = list(data.Category)
8 Y8 D: N! x4 x5 u
2 s; J( b9 X9 a# K8 {0 z for lat, lng, label in zip(latitudes, longitudes, labels):
) v$ k. b' K) Q6 o folium.Marker([lat, lng], popup=label).add_to(
san_map)
1 ^) ~( n. N8 d( {; w% [! E
' Q n8 }8 m8 U9 x. q& h # add incidents to map
; K8 w/ ]( Q1 ~; N# {* s
san_map.add_child(incidents)
+ y7 g* W& @9 J- U* l
- A, b' y" [1 s6 j! t) W 6. 统计区域犯罪总数
) k( P. q& d& v; I& _' \: F from folium import plugins
- U! X$ P) o7 x. {
& q5 b6 s1 m7 h7 A/ Y: l6 d # lets start again with a clean copy of the map of San Francisco
( r, q# ~) D. R: a0 [ san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)
1 p+ `! O& P6 H a
1 t. ?. D, W! ] # instantiate a mark cluster object for the incidents in the dataframe
7 _! G/ Z9 i6 l0 h+ X
incidents = plugins.MarkerCluster().add_to(san_map)
/ J+ q5 G7 \) Y& G1 D( S" B
: L& R- U3 S" d: K) [ # loop through the
dataframe and add each data point to the mark cluster
+ o3 z% t3 d6 V& K3 X5 y+ C for lat, lng, label, in zip(data.Y, data.X, cdata.Category):
3 w. V7 ?5 i- X: F folium.Marker(
* D: u- Y x! Z7 b! F+ w$ K location=[lat, lng],
& E+ J. X. {6 X* y8 o% ?8 C
icon=None,
' i' s1 [2 k* Z" @+ U5 q
popup=label,
* I, g- ^+ w6 R4 W% V3 f ).add_to(incidents)
# M: h1 w! f$ ?4 \/ O+ O; E
8 e0 t# O$ V. E2 T # add incidents to map
- k! f) i1 P5 c san_map.add_child(incidents)
0 L* U8 K% e2 c) I+ T! g' L 1 }& d' u9 w" Q* w
7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界
$ r' k d; M, r* b# k/ _, i
import json4 T: Q9 u5 | P, I. I0 C* Y+ ?
import requests% p0 D" P& Z6 l( D6 D$ ]
+ Q) A: ]; U9 o8 y' } url = https://cocl.us/sanfran_geojson+ ]+ o( m- @) z( J
san_geo = f{url}
2 ?4 [- z1 Z" c( T ]8 D! m san_map = folium.Map(location=[37.77, -122.4], zoom_start=12)5 o2 _, ?7 N2 G4 b h B4 I" r
folium.GeoJson(
' R8 M) O& K' U/ Y9 V w san_geo,$ b5 G9 i2 [8 t- h5 O
style_function=lambda feature: {
) x5 w1 |0 n9 u# N fillColor: #ffff00,
! Q# ?" _+ F4 ~5 e& x) `$ \ color: black,
* z" v3 a! p/ y U weight: 2,
$ F$ a( I/ l/ F4 y. P$ a3 R5 Z% r dashArray: 5, 5
$ m# |2 z& i- E4 T }
" }( B' R7 u7 u: u' g( W ).add_to(san_map)
0 M# @+ N# v' f5 l1 `; E
% d" B; I$ N/ s0 a& @4 o9 d+ l #display map9 [3 [$ u) b+ R
san_map
5 \* P# `& N4 |" ^
. ?4 ]' i" J4 `3 `% O% f+ W
8. 统计每个区域的犯罪事件数目
4 K3 K6 x. h0 W+ K # Count crime numbers in each
neighborhood' n y! W* Q$ z& i1 c5 d# ]$ F
disdata = pd.DataFrame(cdata[PdDistrict].value_counts())
9 j4 P) o+ z6 W1 I( m4 u
disdata.reset_index(inplace=True)
3 G, G8 w. C8 f) ~( \ disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True)
( T& L" x7 T$ v2 J
disdata
3 {0 }; A) b. P7 `; Z9 Z7 H
, r+ Z% f0 A/ C" h* _1 j! p
9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)
0 y o* V* a" G( a2 u m = folium.Map(location=[37.77, -122.4], zoom_start=12)
0 V4 Y* r) ]1 B folium.Choropleth(
8 g( S4 t+ R! x7 w9 Y B geo_data=san_geo,
' d6 I: W t+ |7 ~) j. |
data=disdata,
9 [& C7 J5 p3 L0 E
columns=[Neighborhood,Count],
3 F0 z7 v1 W4 p: H' T9 y" ` key_on=feature.properties.DISTRICT,
: C' H8 \- t! m6 X' J
#fill_color=red,
+ v {6 V% ]8 W: W+ B+ _ fill_color=YlOrRd,
" g$ w2 d( O1 q) Y$ a$ e, k& N fill_opacity=0.7,
' D6 X. M- U, u! {
line_opacity=0.2,
- [0 ]6 I3 _! } highlight=True,
* s0 j3 h4 L1 f8 l8 e
legend_name=Crime Counts in San Francisco
% A9 Z9 p, J: ]& h ).add_to(m)
5 t3 S8 @8 Q6 c& I! { m
1 ^, ?5 c" Q: k% G. |5 u8 V
0 x6 r/ h6 J- o( \3 X
" W' S: ]" m9 C, f$ d% N( P2 {( e
10. 创建热力图
/ Q+ u8 \2 }5 n from folium.plugins import HeatMap* y x) [5 Y! c$ W0 i9 @; B" Y
% C! \6 l" F9 L3 e # lets start again with a clean copy of the map of San Francisco/ `; @3 c+ G6 [" F* @3 o" e
san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)# o9 J+ I: [8 H; J4 v$ X3 g
% M. S5 B( ]- N4 ~% u4 L # Convert data format# d, g2 |- `6 e: O, N5 [1 w
heatdata = data[[Y,X]].values.tolist()1 D! I: c# |- M
: v& a2 n( a! w+ G9 X4 ?* P # add incidents to map
$ U* [) b/ l. F; s8 R HeatMap(heatdata).add_to(san_map)
" `. d% o. |/ o _
* ~- a/ e2 M" U" T san_map
0 q5 {* p1 p* f7 ]) ]
' Q+ V4 l! N" {1 n 最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。
/ b g/ w' A" P8 ]) t
实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。
, @' M h$ I, K7 t- @" X' g3 s
& }- y$ s9 @; \& J' K 我的其他回答:
3 z" C, d2 d8 A2 j* l$ ~ . X6 {5 A) x8 D ?
5 L' I$ z' y+ i; m, y* l
. C- z$ N/ `0 K5 k) W
最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:
: G0 E/ z, ?% g+ m% V
1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=
, ]+ U3 M, `0 o0 D4 \
2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。
7 M3 G$ _9 L7 F- a: u- q" g
给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。
- V- U( j/ w2 V# {( I4 y K
最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!
0 b( f$ r2 t4 E& l