收藏本站 劰载中...网站公告 | 吾爱海洋论坛交流QQ群:835383472

Python 如何画出漂亮的地图?

[复制链接]
! J; i7 r# w6 p, C
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 cdata1 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 plugins1 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 cluster5 ]* ]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 m6 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
( i2 m- h5 Q1 I6 ` ?+ a' I; P. i) m6 `* C+ j' c 2 ]3 t. b9 S. }2 ? / _( h8 N- @ T- ^3 O/ l$ G3 I ! D# [" Z: }! W# s* f
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
风亥
活跃在2026-4-15
快速回复 返回顶部 返回列表