2011-11-25 142 views
12

我有一个宠物项目来创建地图图像,在这里我绘制道路和其他东西在地形高程的等高线图上。它的目的是规划山地自行车路线(我过去曾经手工制作过一些矢量图,而且它们很适合可视化)。隐藏pyplot.contourf上的轮廓线以获得唯一填充

目前,我下载数字高程模型,在GeoTIFF文件,从这里开始: http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar

,然后创建GDAL和Matplotlib contourf功能的情节:其中给出

from osgeo import gdal 
import matplotlib 
import matplotlib.pyplot as plt 
from pylab import cm 
import numpy 

f = 'rs.tif' 

elev = gdal.Open(f) 

a = elev.GetRasterBand(1).ReadAsArray() 

w = elev.RasterXSize 
h = elev.RasterYSize 
print w, h 

altura = (0.35, 0.42) 
largura = (0.70, 0.82) 

a = a[int(h*altura[0]):int(h*altura[1]), 
     int(w*largura[0]):int(w*largura[1])] 


cont = plt.contourf(a, origin='upper', cmap=cm.gist_earth, levels=numpy.arange(0,1000,20)) 
plt.title('Altitudes - max: %d m; min: %d m' % (numpy.amax(a), numpy.amin(a))) 
plt.show() 

enter image description here

问题是轮廓线是“白色”,并产生一些视觉污染,这是不受欢迎的,因为我想稍后再绘制道路和河流。

所以,我想修改的方式contourf创建这些更轻的线路,或者通过参数设置,或通过黑客(更改源代码),类似于一个建议这里:

How to format contour lines from Matplotlib

而且,如果有人知道如何以更优雅的方式生成这样的地图,使用其他库,我会非常感激这个提示!

感谢您的阅读。

回答

20

我终于找到了这个长期存在的问题得到妥善解决(目前Matplotlib 2.0),不需要多次调用轮廓或光栅化图形。

请注意,问题中说明的问题仅出现在保存的出版物质量数字格式(如PDF)中,而不出现在质量较差的栅格文件(如PNG)中。

我的解决方案受到this答案的启发,与彩条的类似问题有关。类似的解决方案证明解决等高线图,以及,如下:

import numpy as np 
import matplotlib.pyplot as plt 

np.random.seed(123) 
x, y = np.random.uniform(size=(100, 2)).T 
z = np.exp(-x**2 - y**2) 
levels = np.linspace(0, 1, 100) 

cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean") 

# This is the fix for the white lines between contour levels 
for c in cnt.collections: 
    c.set_edgecolor("face") 

plt.savefig("test.pdf")  

这里下面是修复

enter image description here

前轮廓的示例,并且这里下面是后同一图上述固定

enter image description here

+2

嗯,当然这是现在被接受的答案,因为它似乎有理由地并且不冒昧地解决了底层问题。时间!! – heltonbiker

+1

感谢@heltonbiker更新它这种解决方案的优点是它不会增加文件大小并且不会降低图像质量。 – divenex

+1

太棒了!我一直在等待这个,我希望在下次需要时我不会忘记检查我喜欢的帖子;) –

3

尝试添加kw argrument到plt.contourf(...)请致电:lw=0ls=Nonehttp://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf

+0

我确实如你所说,我记得之前尝试类似的东西,但遗憾的是它没有工作。我怀疑这些灯光线可能实际上是由于不正确的反锯齿造成的渲染问题,但是怎么能知道? – heltonbiker

+0

老实说,我真的不知道:-(。但有一点令人惊讶的是,在这个例子中,http://matplotlib.sourceforge.net/examples/pylab_examples/contourf_log.html,这些行不在那里。如果我是你,我会从这个例子开始,看看这些线条开始出现在哪里 –

+0

哇!现在看到了惊人的时刻!现在有时间做功课,只要我得到一些结果,我会来回复反馈非常感谢!!! – heltonbiker

5

heltonbiker,你找到了解决你的问题?我不小心偶然发现了这个问题,而且我在一段时间内遇到了同样的问题。我试过振亚的建议,但是,它们也不适合我。问题的解决方案尽管不是真正的解决方案,但更多的解决方法很简单:只需重复相同的contourf命令,这将奇迹般地消除虚假的轮廓。

正如OP所述,当轮廓填充(contourf)间隔过近时,会出现杂散轮廓。

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # 2001 intervals 

这给了我们作为输出:我们可以通过设置一个非常大的数字区间,如重现此问题

enter image description here

瘦伪轮廓明显影响轮廓的净色填。

如果你做两次命令:

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # Not once, 
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # but twice! 

给我:

enter image description here

现在

好多了。这里是最好的之一,连续3个contourf命令:

enter image description here

我看不到任何薄的轮廓了!不幸的是,这可能会显着减慢脚本,具体取决于数组大小和轮廓间隔数。如果使用更多等高线间隔,伪轮廓更突出。通常最适合我的是使用50到100轮廓间隔,并执行contourf两次。

请注意,我使用的matplotlib版本不是最新版本。该问题可能已在版本1.1.0中得到解决。如果有,请告诉我。

Python 2.7.1 |EPD 7.0-2 (32-bit)| (r271:86832, Nov 29 2010, 13:52:51) 
In [1]: matplotlib.__version__ 
Out[1]: '1.0.1' 
+0

非常感谢您对旧问题的关注!我很确定这个问题与锯齿效应有关,像素在边界处没有“着色”。这与您的解决方案非常吻合,因为重新绘制半透明(或半“未着色”)像素倾向于“填充它们”并将它们着色。我现在不能尝试这个建议,但是当我到时候(我的地块不那么密集以至于有令人望而却步的性能问题)时,我肯定会这样做。谢谢!! – heltonbiker

+0

(而且这是一个耻辱,与Ubuntu相关的发行版的最新版本仍在使用matplotlib 0.9 ...) – heltonbiker

+0

@heltonbiker它是。我在Fedora,RHEL和CentOS上使用Enthought Python Distribution,我会强烈推荐它。matplotlib 1.1.0自带了许多其他面向科学的模块。显然,我没有使用最新的EPD版本:)。 http://enthought.com/products/epd.php(我与Enthought不相关) – milancurcic