Как построить пунктирные линии из шейп-файла в Python?

Я не уверен, как построить пунктирную линию из шейп-файла в Python. Похоже, что readshapefile() не имеет никакого стиля линии для меня, чтобы установить. Ниже у меня есть рабочий код, где я беру шейп-файл и строю его, но он отображает только сплошную линию. Любые идеи, чтобы установить меня в правильном направлении? Спасибо!

Шейп-файл можно найти здесь: http://www.natice.noaa.gov/products/daily_products.html, где начальная дата - 15 февраля, конечная дата - 17 февраля, а тип даты - Ice Edge. Это должна быть первая ссылка.

#!/awips2/python/bin/python

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

map = Basemap(llcrnrlon=-84.37,llcrnrlat=42.11,urcrnrlon=-20.93,urcrnrlat=66.48,
     resolution='i', projection='tmerc', lat_0 = 55., lon_0 = -50.)

map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#ddaa66',lake_color='aqua')
map.drawcoastlines(zorder = 3)

map.readshapefile('nic_autoc2018046n_pl_a', 'IceEdge', zorder = 2, color = 'blue')

plt.show()

1 ответ

Из документации базовой карты:

Возвращается кортеж (num_shapes, type, min, max), содержащий информацию о файле формы. num_shapes - это число фигур, type - это код типа (одна из констант SHPT*, определенных в модуле shapelib, см. http://shapelib.maptools.org/shp_api.html), а min и max - это 4-элементные списки с минимальные и максимальные значения вершин. Если drawbounds=True, к кортежу добавляется объект matplotlib.patches.LineCollection.

drawbounds является True по умолчанию, так что все, что вам нужно сделать, это собрать возвращаемое значение readshapefile и изменить linestyle из возвращенных LineCollection объект, который можно сделать с LineCollection.set_linestyle(), Таким образом, в принципе вы можете изменить стиль линии вашего построенного файла формы следующим образом:

result = m.readshapefile('shapefiles/nic_autoc2018046n_pl_a', 'IceEdge', zorder = 10, color = 'blue')#, drawbounds = False)
col = result[-1]
col.set_linestyle('dotted')
plt.show()

Тем не менее, ваш shapefile содержит 5429 отдельных линейных сегментов разной длины, и почему-то matplotlib, похоже, не в состоянии справиться с таким большим количеством непостоянных линий. По крайней мере, на моей машине прорисовка не завершилась в течение часа, поэтому я прервал процесс. Я немного поиграл с вашим файлом, и кажется, что многие из линий разбиты на сегменты без необходимости (я предполагаю, что это потому, что контуры ледяного покрова каким-то образом определены на плитках, а затем сложены вместе, но только поставщики действительно будут знать,). Может быть, это поможет собрать воедино соседние кусочки, но я не уверен.

Я также задавался вопросом, будет ли результат даже выглядеть так здорово с пунктирной линией, потому что есть так много острых изгибов. Ниже я показываю рисунок, на котором я строю только 100 самых длинных отрезков drawcoastlines и с более толстыми линиями), используя этот код:

import numpy as np
result = m.readshapefile('shapefiles/nic_autoc2018046n_pl_a', 'IceEdge', zorder = 10, color = 'blue')#, drawbounds = False)

col = result[-1]
segments = col.get_segments()
seglens =  [len(seg) for seg in col.get_segments()]

segments = np.array(segments)
seglens  = np.array(seglens)

idx = np.argsort(seglens)
seglens  = seglens[idx]
segments = segments[idx]

col.remove()

new_col = LineCollection(segments[-100:],linewidths = 2, linestyles='dotted', colors='b')
ax.add_collection(new_col)

plt.show()

И результат выглядит так:

результат второго патча кода

Другие вопросы по тегам