简体   繁体   English

在 pyplot.contourf 上隐藏轮廓线以仅获取填充

[英]Hide contour linestroke on pyplot.contourf to get only fills

I have a pet project to create images of maps, where I draw the roads and other stuff over a contour plot of the terrain elevation.我有一个创建地图图像的宠物项目,在那里我在地形高程的等高线图上绘制道路和其他东西。 It is intended to plan mountain bike routes (I have made some vectorial drawings by hand, in the past, and they work great for visualization).它的目的是规划山地自行车路线(过去我手工制作了一些矢量图,它们非常适合可视化)。

Currently, I download Digital Elevation Model, in GeoTIFF, from here: http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar目前,我从这里下载 GeoTIFF 中的数字高程模型: http : //www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar

and then create the plot with GDAL and Matplotlib contourf function:然后使用 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()

Which gives:这使:

在此处输入图片说明

The problem is that contour lines are "white", and generate some visual pollution, which is undesired since I want to plot roads and rivers later.问题是等高线是“白色”的,会产生一些视觉污染,这是不希望的,因为我以后想绘制道路和河流。

So, I am trying to modify the way contourf create these lighter lines, either via parameter setting, or via hack (changing source code), similar to the one proposed here:因此,我试图通过参数设置或通过 hack(更改源代码)来修改contourf创建这些较轻线条的方式,类似于此处提出的方法:

How to format contour lines from Matplotlib 如何从 Matplotlib 格式化轮廓线

Also, if anyone knows how to generate such a map in a more elegant way, using other libraries, I would appreciate the tip very much!另外,如果有人知道如何使用其他库以更优雅的方式生成这样的地图,我将非常感谢您的提示!

Thanks for reading.谢谢阅读。

I finally found a proper solution to this long-standing problem (currently in Matplotlib 3), which does not require multiple calls to contour or rasterizing the figure.我终于找到了解决这个长期存在的问题(目前在 Matplotlib 3 中)的合适解决方案,它不需要多次调用轮廓或光栅化图形。

Note that the problem illustrated in the question appears only in saved publication-quality figures formats like PDF, not in lower-quality raster files like PNG.请注意,问题中说明的问题仅出现在保存的出版质量图形格式(如 PDF)中,而不出现在质量较低的光栅文件(如 PNG)中。

My solution was inspired by this answer, related to a similar problem with the colorbar.我的解决方案受到这个答案的启发,与颜色栏的类似问题有关。 A similar solution turns out to solve the contour plot as well, as follows:结果证明,类似的解决方案也可以解决等高线图,如下所示:

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")    

Here below is an example of contours before the fix以下是修复前的轮廓示例

在此处输入图片说明

And here below is the same figure after the above fix下面是上面修复后的同一个图

在此处输入图片说明

The solution to the problem, despite not being a real solution, but more a workaround, is simple: Just repeat the same contourf command and this will magically get rid of spurious contours.该问题的解决方案虽然不是真正的解决方案,而是一种解决方法,但很简单:只需重复相同的contourf命令,这将神奇地摆脱虚假轮廓。

As stated by the OP, spurious contours show up when doing contour fill ( contourf ) with intervals too close to each other.正如 OP 所述,在间隔太近的情况下进行轮廓填充 ( contourf ) 时,会出现虚假轮廓。 We can reproduce this behavior by setting a very large number of intervals, eg:我们可以通过设置大量间隔来重现这种行为,例如:

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

This gives us as output:这给了我们作为输出:

在此处输入图片说明

The thin spurious contours obviously affect the net color of the contour fill.细的虚假轮廓明显影响轮廓填充的净颜色。

If you do the command twice:如果你执行两次命令:

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!

gives me:给我:

在此处输入图片说明

Much better now.现在好多了。 Here's the finest one, with 3 successive contourf commands:这是最好的,有 3 个连续的contourf命令:

在此处输入图片说明

I can't see any thin contours anymore!我再也看不到任何细小的轮廓了! Unfortunately, this may slow down your scripts significantly, depending on array size and number of contour intervals.不幸的是,这可能会显着减慢您的脚本速度,具体取决于数组大小和等高线间隔的数量。 The spurious contours stand out more if more contour intervals are used.如果使用更多的等高线间隔,虚假等高线会更加突出。 What usually works best for me is to use 50 to 100 contour intervals, and do the contourf twice.通常什么最适合我是用50〜100线距,并做contourf两次。

Notice that the version of matplotlib I am using is not the latest one.请注意,我使用的 matplotlib 版本不是最新版本。 This issue might have been resolved in version 1.1.0 .此问题可能已在1.1.0版中解决。 If it has, please let me know.如果有,请告诉我。

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'

The posted solution did not work for me with alpha set to <1, but I found the answer in this solution: Matplotlib Contourf Plots Unwanted Outlines when Alpha < 1当 alpha 设置为 <1 时,发布的解决方案对我不起作用,但我在这个解决方案中找到了答案: Matplotlib Contourf Plots Unwanted Outlines when Alpha < 1

Adding the argument antialiased=True solved the issue for me.添加参数antialiased=True为我解决了这个问题。

Try adding the kw argrument to plt.contourf(...) call: either lw=0 or ls=None .尝试将 kw 参数添加到plt.contourf(...)调用: lw=0ls=None http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM