Как построить пунктирные линии из шейп-файла в 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()
И результат выглядит так: