首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有matplotlib / Basemap的没有河流的世界地图?

有matplotlib / Basemap的没有河流的世界地图?
EN

Stack Overflow用户
提问于 2013-01-11 22:34:07
回答 7查看 13.5K关注 0票数 20

有没有一种方法可以用底图绘制大陆的边界(如果有其他方法,也可以不用底图),而不需要那些恼人的河流?特别是那段金戈河,甚至没有到达海洋,是令人不安的。

编辑:我打算在地图上进一步绘制数据,就像在Basemap gallery中一样(仍然将各大洲的边界线绘制为数据上的黑线,以给出世界地图的结构),所以虽然下面挂钩的解决方案很好,甚至很精通,但它不适用于此目的。

图片制作人:

代码语言:javascript
复制
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 4.5))
plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.00)
m = Basemap(projection='robin',lon_0=0,resolution='c')
m.fillcontinents(color='gray',lake_color='white')
m.drawcoastlines()
plt.savefig('world.png',dpi=75)
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-01-18 22:11:19

按照user1868739的例子,我只能选择我想要的路径(对于一些湖):

代码语言:javascript
复制
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 4.5))
plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.00)
m = Basemap(resolution='c',projection='robin',lon_0=0)
m.fillcontinents(color='white',lake_color='white',zorder=2)
coasts = m.drawcoastlines(zorder=1,color='white',linewidth=0)
coasts_paths = coasts.get_paths()

ipolygons = range(83) + [84] # want Baikal, but not Tanganyika
# 80 = Superior+Michigan+Huron, 81 = Victoria, 82 = Aral, 83 = Tanganyika,
# 84 = Baikal, 85 = Great Bear, 86 = Great Slave, 87 = Nyasa, 88 = Erie
# 89 = Winnipeg, 90 = Ontario
for ipoly in ipolygons:
    r = coasts_paths[ipoly]
    # Convert into lon/lat vertices
    polygon_vertices = [(vertex[0],vertex[1]) for (vertex,code) in
                        r.iter_segments(simplify=False)]
    px = [polygon_vertices[i][0] for i in xrange(len(polygon_vertices))]
    py = [polygon_vertices[i][2] for i in xrange(len(polygon_vertices))]
    m.plot(px,py,linewidth=0.5,zorder=3,color='black')

plt.savefig('world2.png',dpi=100)

但这只在大陆使用白色背景时有效。如果我在下面的代码行中将color更改为'gray',我们会看到其他河流和湖泊的颜色与大陆不同。(此外,玩area_thresh也不会删除那些连接到海洋的河流。)

代码语言:javascript
复制
m.fillcontinents(color='gray',lake_color='white',zorder=2)

白色背景的版本足以进一步彩色绘制各大洲的各种陆地信息,但如果想要保留各大洲的灰色背景,则需要一个更复杂的解决方案。

票数 3
EN

Stack Overflow用户

发布于 2013-01-12 00:11:27

由于这样的原因,我经常避免把底图都放在一起,用OGR读取shapefile,然后自己把它们转换成Matplotlib艺术家。这是更多的工作,但也给了更多的灵活性。

底图有一些非常简洁的功能,比如将输入数据的坐标转换为你的“工作投影”。

如果你想坚持使用底图,那就得到一个不包含河流的shapefile。例如,Natural Earth在物理部分有一个很好的'Land‘shapefile (下载'scale rank’数据并解压缩)。请参阅http://www.naturalearthdata.com/downloads/10m-physical-vectors/

您可以使用m.readshapefile()方法从底图中读取shapefile。这允许您获得Matplotlib路径顶点和投影坐标中的代码,然后可以将其转换为新路径。这有点绕道,但它为你提供了Matplotlib的所有样式选项,其中大部分不能通过底图直接使用。这有点老生常谈,但我现在没有另一种方式,同时坚持底图。

所以:

代码语言:javascript
复制
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.collections import PathCollection
from matplotlib.path import Path

fig = plt.figure(figsize=(8, 4.5))
plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.00)

# MPL searches for ne_10m_land.shp in the directory 'D:\\ne_10m_land'
m = Basemap(projection='robin',lon_0=0,resolution='c')
shp_info = m.readshapefile('D:\\ne_10m_land', 'scalerank', drawbounds=True)
ax = plt.gca()
ax.cla()

paths = []
for line in shp_info[4]._paths:
    paths.append(Path(line.vertices, codes=line.codes))

coll = PathCollection(paths, linewidths=0, facecolors='grey', zorder=2)

m = Basemap(projection='robin',lon_0=0,resolution='c')
# drawing something seems necessary to 'initiate' the map properly
m.drawcoastlines(color='white', zorder=0)

ax = plt.gca()
ax.add_collection(coll)

plt.savefig('world.png',dpi=75)

提供:

票数 12
EN

Stack Overflow用户

发布于 2013-01-12 00:10:21

如何清除“烦人”的河流:

如果要对图像进行后处理(而不是直接使用底图),可以删除未连接到海洋的水体:

代码语言:javascript
复制
import pylab as plt
A = plt.imread("world.png")

import numpy as np
import scipy.ndimage as nd
import collections

# Get a counter of the greyscale colors
a      = A[:,:,0]
colors = collections.Counter(a.ravel())
outside_and_water_color, land_color = colors.most_common(2)

# Find the contigous landmass
land_idx = a == land_color[0]

# Index these land masses
L = np.zeros(a.shape,dtype=int) 
L[land_idx] = 1
L,mass_count = nd.measurements.label(L)

# Loop over the land masses and fill the "holes"
# (rivers without outlays)
L2 = np.zeros(a.shape,dtype=int) 
L2[land_idx] = 1
L2 = nd.morphology.binary_fill_holes(L2)

# Remap onto original image
new_land = L2==1
A2 = A.copy()
c = [land_color[0],]*3 + [1,]
A2[new_land] = land_color[0]

# Plot results
plt.subplot(221)
plt.imshow(A)
plt.axis('off')

plt.subplot(222)
plt.axis('off')
B = A.copy()
B[land_idx] = [1,0,0,1]
plt.imshow(B)

plt.subplot(223)
L = L.astype(float)
L[L==0] = None
plt.axis('off')
plt.imshow(L)

plt.subplot(224)
plt.axis('off')
plt.imshow(A2)

plt.tight_layout()  # Only with newer matplotlib
plt.show()

第一幅图像是原始图像,第二幅图像识别陆地块。第三个不是必需的,但很有趣,因为它的ID是每个独立的连续陆地。第四张图片是你想要的,去掉了“河”的图片。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14280312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档