Спрятать контурные линии на pyplot.contourf, чтобы получать только заливки - PullRequest
19 голосов
/ 25 ноября 2011

У меня есть домашний проект для создания изображений карт, на которых я рисую дороги и другие объекты на контурной диаграмме рельефа местности. Он предназначен для планирования маршрутов для горных велосипедов (в прошлом я уже делал несколько векторных рисунков вручную, и они отлично работают для визуализации).

В настоящее время я загружаю Цифровую модель рельефа в 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 создавать эти более легкие строки, либо с помощью установки параметров, либо с помощью хака (изменение исходного кода), аналогично тому, который предлагается здесь:

Как отформатировать контурные линии из Matplotlib

Кроме того, если кто-нибудь знает, как создать такую ​​карту более элегантным способом, используя другие библиотеки, я был бы очень признателен за подсказку!

Спасибо за чтение.

Ответы [ 4 ]

30 голосов
/ 02 октября 2015

Я наконец нашел правильное решение этой давней проблемы (в настоящее время в Matplotlib 2.0), которая не требует многократных вызовов для контура или растеризации фигуры.

Обратите внимание, что проблема, показанная в вопросе, появляется только в сохраненных форматах качества публикации, таких как PDF, а не в растровых файлах низкого качества, таких как PNG.

Мое решение было вдохновлено этим ответом, связанным с аналогичной проблемой с цветовой шкалой.Аналогичное решение, как выясняется, решает и контурный график следующим образом:

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

6 голосов
/ 17 мая 2012

heltonbiker, вы нашли решение своей проблемы?Я случайно наткнулся на этот вопрос, и некоторое время у меня была та же проблема.Я попробовал предложения Жени, однако они тоже не работают для меня.Решение проблемы, несмотря на то, что это не реальное решение, а скорее обходной путь, простое: просто повторите ту же команду contourf, и это волшебным образом избавит от паразитных контуров.

Как указано в ОПпри заполнении контура (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

Теперь намного лучше.Вот самая лучшая из трех последовательных 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'
4 голосов
/ 25 ноября 2011

Попробуйте добавить аргумент kw к вызову plt.contourf(...): либо lw=0, либо ls=None. http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf

2 голосов
/ 21 марта 2018

Опубликованное решение не работает для меня с альфа-значением <1, но я нашел ответ в этом решении: <a href="https://stackoverflow.com/questions/15192661/matplotlib-contourf-plots-unwanted-outlines-when-alpha-1"> Matplotlib Contourf отображает нежелательные контуры, когда альфа <1 </a>

Добавление аргумента antialiased=True решило проблему для меня.

...