Python 如何画出漂亮的地图?

[复制链接]
! `% w5 ]+ y) s( X f' }4 w' P
- l- p/ h, o3 Q& u5 e

推荐一个超好用的python包folium, 专门用于地理数据可视化,官方英文教程教程点击这里

7 n6 D. C0 u6 g- S
4 ^# U+ d- w s7 H

使用方法很简单,操作如下:

导入包,创建一副世界地图, l5 j/ z& d3 D$ d* F) _
import folium - U. \2 c' e0 ` import pandas as pd7 K( | x# i- C& w % l" E7 ~% J& c7 N! s # define the world map% o/ R* O2 G8 U: m+ V+ T/ F world_map = folium.Map() / I4 |# t, ~' n) ~$ e2 [% _+ t3 ?4 N* v( C; k4 W # display world map ) u, Q! u. H+ b" i world_map
) Q: }: x; N M: B- E& }& _' o& I
, w' _8 p. I& L! y3 C0 g0 |! |

2. 输入经纬度,尺度,在这里我们以旧金山(37.7749° N, 122.4194° W)为例。

7 @) j- y5 G4 o5 N5 m
# San Francisco latitude and longitude values - k* b; D [/ G9 B# y/ D latitude = 37.77 * K1 R; f/ k) z. q* X7 p longitude = -122.42 ! S% G1 J4 o6 n + |* K5 o+ }3 @/ L; u3 i # Create map and display it % y2 p) y9 S) O; o# h# u san_map = folium.Map(location=[latitude, longitude], zoom_start=12) G1 A7 d5 d R/ p- k0 ~. V* P4 I% }) v% B* @9 g8 {' e # Display the map of San Francisco* r F5 [! N2 b# o san_map
% n5 U3 N* T' c6 h3 E8 e
+ Q3 p. d, \7 o8 f" T

更改地图显示,默认为OpenStreetMap风格,我们还可以选择Stamen Terrain, Stamen Toner等。

3 Q5 R5 R) v0 K: ^' y
# Create map and display it 7 @% r0 L! Z: X5 f0 ` san_map = folium.Map(location=[latitude, longitude], zoom_start=12,tiles=Stamen Toner)
# b1 o0 l4 o7 X% x( x- n) [0 }4 z
) o9 ?9 S$ z* _. q' V( I

3. 读取数据集(旧金山犯罪数据集)

: M) l7 C5 i! z% m& S0 ]: E
# Read Dataset ! l6 Z1 Y; a0 |7 s: B1 i8 q cdata = pd.read_csv(https://cocl.us/sanfran_crime_dataset) ( E' Q8 A4 u8 ~) ]/ q, X4 r8 H cdata.head()
& [9 G% A* \& E, ]# ] x
& W3 C9 Z# N8 s% {6 g

4. 在地图上显示前200条犯罪数据

7 E0 B; @* T+ t& s# e, l4 ~- m
# get the first 200 crimes in the cdata 6 b4 E: C9 L7 @2 ^ G limit = 200 ; l3 C# a6 B$ k3 L3 |8 n data = cdata.iloc[0:limit, :]1 ^% e5 u- |* f7 A3 y8 A : J Z7 R9 a' q$ H/ b1 u: n' n # Instantiate a feature group for the incidents in the dataframe5 a: ]/ y. n/ S; Y# |$ R0 C2 G incidents = folium.map.FeatureGroup()6 r6 F" v+ n+ P' `+ b 3 I/ U/ N( L' N- }6 c # Loop through the 200 crimes and add each to the incidents feature group6 o5 [* f9 c) K$ z! J for lat, lng, in zip(cdata.Y, data.X):6 e {3 W+ e! D( j+ a incidents.add_child( - }& }$ i4 w4 m& E) R9 e folium.CircleMarker( 9 m4 H4 @9 n9 H7 T% I. @ [lat, lng],# z J% `' M! ?4 w radius=7, # define how big you want the circle markers to be 7 `) Q5 T; |" o8 e color=yellow,; X. L& F- ]( u( h fill=True, 4 }0 a8 m! s2 } m6 u8 y fill_color=red, 1 E7 X6 R! [! B: a6 N$ A fill_opacity=0.4 ' @6 X0 v3 ~! v0 E )4 G9 C, h- g$ T. G ) . E% [8 E3 N6 D: e& O+ F" n& t Y( s) h9 {, u # Add incidents to map+ F* _" z7 z9 P: E6 R) c2 q7 h san_map = folium.Map(location=[latitude, longitude], zoom_start=12)) @! C3 e" s& V8 b san_map.add_child(incidents)
* w! G% _# j. e& M
/ |- u8 J/ `2 L7 p1 d/ E' Q

5. 添加地理标签

6 z5 C( S# L* p; n* V5 h" i' M( U* c
# add pop-up text to each marker on the map % r2 I5 t) ?% W) u9 A+ ~ latitudes = list(data.Y)1 \5 d1 w4 v2 k/ w longitudes = list(data.X)' q" r; m. t+ E: o) F- a1 Y' r/ e5 U labels = list(data.Category)' q0 r" I# m8 U ; B o" {) |( o( E* {, y for lat, lng, label in zip(latitudes, longitudes, labels):$ r: c9 S, m; C" _) b- g folium.Marker([lat, lng], popup=label).add_to(san_map) 2 C; T4 j0 G1 P H" A T& e) V# n0 Y, Y# p* x # add incidents to map) Q: Z) H7 ]9 M' B/ _ san_map.add_child(incidents)
1 N. l- V8 ?! ]: a
5 [. E! \6 @# s0 ]" T

6. 统计区域犯罪总数

2 e- `3 ]7 k/ `7 T- N& n- U2 e
from folium import plugins! Q) y: ]# F A: U+ `; S . ~2 T5 {) X, i' T: u # lets start again with a clean copy of the map of San Francisco ) J" [* n4 f: ~* M5 l' d, S! I6 A" { san_map = folium.Map(location = [latitude, longitude], zoom_start = 12)0 ^8 |' O2 M! u! h# G, r' I1 F, y ! x D; k9 d" s }# L7 T # instantiate a mark cluster object for the incidents in the dataframe! ^6 W/ _! h( }& ^ incidents = plugins.MarkerCluster().add_to(san_map) 2 \ [7 B4 o; T4 n) M & m2 g# [# S; U7 a # loop through the dataframe and add each data point to the mark cluster& a3 Q, U3 ~+ U& }& `$ ~) k H/ _ for lat, lng, label, in zip(data.Y, data.X, cdata.Category):) ?- g3 W0 y* _2 Q6 e9 ]$ X6 O folium.Marker( }2 p: G- _) x! [( D location=[lat, lng],( U) Q8 g/ d; P: T/ `3 e1 e icon=None, 9 u% O8 \- _6 }- p Z3 R popup=label, 8 ?6 t* _7 |! r( C ).add_to(incidents) $ f2 k; ^. `% R& u# w: }( b+ Q, P, h( E9 `7 `+ { # add incidents to map ; @1 Q4 c% \. n) e) g+ t san_map.add_child(incidents)
2 @0 S/ s: z- v/ A- @2 N! c
, i$ ]; z: N9 Q

7. 读取geojson文件,可视化旧金山市10个不同Neighborhood的边界

/ J) U4 J7 B4 F& r
import json3 e7 _; @% c/ e7 R import requests % }5 v6 p% ]2 S5 C0 h6 c4 C8 j! P5 `5 e2 Q3 a( }" | url = https://cocl.us/sanfran_geojson; x; o3 o8 h( j: v# J. l ^ Y) b san_geo = f{url}, S# C6 \$ s% d7 v! b2 @ san_map = folium.Map(location=[37.77, -122.4], zoom_start=12) " S* R* ^7 v+ m; e; n$ V% b4 d folium.GeoJson(6 A: \ y, T' ], ~" M5 _. l san_geo, % \) P6 H. J7 | style_function=lambda feature: { , d; M& M! |3 ]7 D7 Z; v fillColor: #ffff00,8 U ~- _; f3 s% { color: black,: \1 W1 m! m1 F0 x weight: 2, . d, }( T4 y( f dashArray: 5, 58 q$ F7 I$ c6 Z }! R7 W/ L6 u2 M' @4 o0 n+ s$ d ).add_to(san_map) 5 B, B, g1 a2 H+ \% C# M0 n7 W( U4 V5 u #display map! I! g g4 m% K& S san_map
" `) R+ D! A9 t( L: k
2 G, b1 ^0 m( Y' i. @

8. 统计每个区域的犯罪事件数目

* N8 t6 m' K9 s1 C
# Count crime numbers in each neighborhood , w; o4 N& N) w2 Y; R/ p: M disdata = pd.DataFrame(cdata[PdDistrict].value_counts()) 3 H) L, a0 n" a( R& A disdata.reset_index(inplace=True)9 }1 I! c7 H8 B7 X2 Y disdata.rename(columns={index:Neighborhood,PdDistrict:Count},inplace=True) & F$ m' U* ~0 M disdata
6 ?$ y9 |( V3 x, j
! u- Y2 x" N) y6 B9 ]

9. 创建Choropleth Map (颜色深浅代表各区犯罪事件数目)

+ z" p6 `( s) P' n* }7 v4 o0 \( Y
m = folium.Map(location=[37.77, -122.4], zoom_start=12)# c2 S. o, y0 T6 q2 p folium.Choropleth( ! ^1 L' a. Z0 C/ r/ i# l geo_data=san_geo, 0 i+ F$ v# `: i data=disdata,5 ^9 \( d0 M7 p6 G" h columns=[Neighborhood,Count], " e! @" R0 S7 w key_on=feature.properties.DISTRICT, 6 d; p+ A9 [" f7 Z& c #fill_color=red, 2 u `& X, }9 `2 j' |4 M5 i4 ^ fill_color=YlOrRd, 7 w; l" A$ E2 |: B( Y l fill_opacity=0.7, + `; c6 s- S+ k& N+ |: t# X line_opacity=0.2, ; m$ a1 [8 h# V; T0 w; I7 n' G5 l highlight=True,( [, B/ ^+ m& c# Q5 b6 _ legend_name=Crime Counts in San Francisco: Y) e# E- D$ L |' \ ).add_to(m). S0 T+ j; ?% L; V$ n m 5 g3 S$ |; p# x4 ^# T$ r2 f$ A# K
2 `- h6 L6 c$ i* y/ {( B
* v$ O& E( w$ L8 U

10. 创建热力图

4 S7 c- Z1 q6 B a
from folium.plugins import HeatMap 8 v5 @( M/ n: F ( |% {8 w7 L( X0 v1 J/ e' | # lets start again with a clean copy of the map of San Francisco 4 K# ~% v( P) b! P2 y2 } san_map = folium.Map(location = [latitude, longitude], zoom_start = 12) 9 q, ]4 C& |& k. @+ |1 S* @5 r' Z- y) q& K9 x4 p # Convert data format4 z# H5 j. M8 c/ L4 _& n heatdata = data[[Y,X]].values.tolist()% l* p) F+ C2 M5 \) [% F! O, H, I) | 4 I6 ~, C* W4 G4 @ # add incidents to map : B, k3 y4 c1 M4 c* [ HeatMap(heatdata).add_to(san_map) 0 Z& ?0 V6 s* K5 g P8 E( n# L% j0 s% d san_map
$ U: k6 n" `& ]' b9 Q
& Y2 m, h" I/ ?! M5 i

最后,folium还可以用来创建动态热力图,动态路径图等,具体可参考Medium上的这篇文章。

, z" P' f/ a" ?2 u2 o% m8 B5 {3 Q

实现效果如下图所示 (直接从Medium上抱过来的图,详细代码请点击上述链接)。

- X2 L' u: ^5 C, F5 i
. x" d. \" k" @

我的其他回答:

$ K; m& H# P) d+ [5 h: t4 _0 B & _( d# U0 d* e" ^) C* [ 6 V! D2 _3 c& _+ ]! M 8 L* l5 [& c4 V- P- i

最近有小伙伴私信我推荐一些学习编程的经验,我给大家几点建议:

8 i* j' o( p4 C0 A6 ]1 X3 u

1. 尽量不去看那些冗长的视频教程,不是说学不到知识,而是,在你学到知识之前,你可能已经睡着了 =_=

5 `) w6 b, H- W

2. 不要贪多,选一个知名度高的python教程,教学为辅,练习为主。要随时记住,我们学习python的目的在于会用,而不是背过了多少知识点。

# Q3 y( z* ~+ X0 D

给大家推荐一款我超喜欢的python课程——夜曲编程。我闲没事在上面刷了一些编程题目,竟回想起当年备考雅思时被百词斩支配的恐惧。这款课程对新手小白很适合。虽然有手机app,但我建议你们用网页端学习哈。

" J3 J- T" c% |) n

最后,我的终极建议是:无论选什么教程,贪多嚼不烂,好好专注一门课程,勤加练习才是提高编程水平的王道。等基础知识学的差不多了,去Kaggle上参加几场比赛,琢磨琢磨别人的编程思路和方法就完美啦!

( y7 {9 Q; o8 `. l# v
. M0 t4 \. b: c* ^8 y * K" o+ L' o% \" I# Z# O. d5 E) D- ?# u/ t 2 d. q5 A% i8 c1 [ ' ]) O, ]: d: j* t9 y. e+ u

相关帖子

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