有没有一种方法可以用底图绘制大陆的边界(如果有其他方法,也可以不用底图),而不需要那些恼人的河流?特别是那段金戈河,甚至没有到达海洋,是令人不安的。
编辑:我打算在地图上进一步绘制数据,就像在Basemap gallery中一样(仍然将各大洲的边界线绘制为数据上的黑线,以给出世界地图的结构),所以虽然下面挂钩的解决方案很好,甚至很精通,但它不适用于此目的。
图片制作人:
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)
发布于 2013-01-18 22:11:19
按照user1868739的例子,我只能选择我想要的路径(对于一些湖):
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
也不会删除那些连接到海洋的河流。)
m.fillcontinents(color='gray',lake_color='white',zorder=2)
白色背景的版本足以进一步彩色绘制各大洲的各种陆地信息,但如果想要保留各大洲的灰色背景,则需要一个更复杂的解决方案。
发布于 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的所有样式选项,其中大部分不能通过底图直接使用。这有点老生常谈,但我现在没有另一种方式,同时坚持底图。
所以:
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)
提供:
发布于 2013-01-12 00:10:21
如何清除“烦人”的河流:
如果要对图像进行后处理(而不是直接使用底图),可以删除未连接到海洋的水体:
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是每个独立的连续陆地。第四张图片是你想要的,去掉了“河”的图片。
https://stackoverflow.com/questions/14280312
复制相似问题