matplotlib을 사용하여 shapefile 플롯


15

shapefile을 읽고 matplotlib을 사용하여 플롯하려고합니다. 코드는 다음과 같습니다.

import matplotlib.pyplot as plt
import shapefile   

shpFilePath = "D:\test.shp"  
listx=[]
listy=[]
test = shapefile.Reader(shpFilePath)
for sr in test.shapeRecords():
    for xNew,yNew in sr.shape.points:
        listx.append(xNew)
        listy.append(yNew)
plt.plot(listx,listy)
plt.show()

그러나 다각형을 연결하는 선이 나타납니다. 다각형이 shapefile에있는 방식으로 다각형을 그리는 방법은 무엇입니까? 다음은 ArcGIS로 열린 플롯 및 쉐이프 파일의 스크린 샷입니다.코드로 생성 실제 파일


shapefile 리더에 익숙하지는 않지만 각 모양을 구성 요소 부분으로 분리하지 않고 파일의 모든 점을 하나의 큰 목록에 추가하고 있다고 말할 수 있습니다. 각 셰이프 포인트를 추가 할 수있는 많은 셰이프 목록이 필요합니다.

권리. 모양을 분리하는 방법을 찾아야합니다. 그러나 그것은 내가 지금 할 수없는 일입니다.
statBeginner

@DanPatterson 모양을 분리 한 후 같은 그림에 여러 모양을 그리는 방법을 지정할 수 있습니까? 모든 모양에 대해 plt.plot (listx, listy)를 사용하면 동일한 그림을 사용하는 대신 매번 새로운 그림을 생성합니다.
statBeginner

답변:


10

도형을 모으는 방법을 알려 드리지만 이것이 원칙입니다

import numpy as np
from matplotlib import pyplot as p  #contains both numpy and pyplot
x1 = [-1,-1,10,10,-1]; y1 = [-1,10,10,-1,-1]
x2 = [21,21,29,29,21]; y2 = [21,29,29,21,21]
shapes = [[x1,y1],[x2,y2]]
for shape in shapes:
  x,y = shape
  p.plot(x,y)
p.show()

오 .. 내가 어떻게 그리웠는지 궁금해. 그래도 모양이 다른 색상으로 인쇄됩니다. 그 :) 해결해야합니까
statBeginner

다른 모양을 얻거나 격리하는 방법?
FaCoffee 2016 년

15

나중에 참조 할 수 있도록 위의 조언을 따른 후 온 해결책이 있습니다.

import shapefile as shp  # Requires the pyshp package
import matplotlib.pyplot as plt

sf = shp.Reader("test.shp")

plt.figure()
for shape in sf.shapeRecords():
    x = [i[0] for i in shape.shape.points[:]]
    y = [i[1] for i in shape.shape.points[:]]
    plt.plot(x,y)
plt.show()

결과 그림은 매우 화려하지만 플롯 키워드를 조정하면됩니다.


6
나는이 중복 정보를 수 있습니다 알고 있지만, 주제에 아직 익숙하지 않은 사람들을 위해 그 말을 유용했을 것이다 import shapefile받는 의미 pyshp패키지 : pypi.python.org/pypi/pyshp
FaCoffee

이 지점이 본토의 지점과 선으로 연결되어 OP가 게시 한 것과 유사한 것을 생성하기 때문에 여러 섬이있는 경우에는 문제가되지 않습니다.
FaCoffee

1
@FaCoffee, 네 말이 맞아. 내 대답 gis.stackexchange.com/a/309780/126618이이 문제 를 해결해야합니다.
거스

9

matplotlib 경로패치 를 사용해야 하며 이러한 함수 Descartes를 사용하여 shapefile에서 다각형을 플로팅하기위한 전용 Python 모듈이 있습니다 .

Pyshp (shapefile)에는 geo_interface ( PyShp의 경우 새 geo_interface ) 규칙이 있으므로이를 사용할 수 있습니다.

polys  = shapefile.Reader("polygon")
# first polygon
poly = polys.iterShapes().next().__geo_interface__
print poly
{'type': 'Polygon', 'coordinates': (((151116.87238259654, 135890.8706318218), (153492.19971554304, 134793.3055883224), (153934.50204650551, 133892.31935858406), (152623.97662143156, 131811.86024627919), (150903.91200102202, 130894.49244872745), (149347.66305874675, 132991.33312884573), (149151.08424498566, 134383.76639298678), (151116.87238259654, 135890.8706318218)),)}

결과는 지오메트리의 GeoJSON 표현이며 matplotlib / python을 사용하여 지리 데이터를 플롯하는 방법 의 솔루션을 사용할 수 있습니다

import matplotlib.pyplot as plt 
from descartes import PolygonPatch
BLUE = '#6699cc'
fig = plt.figure() 
ax = fig.gca() 
ax.add_patch(PolygonPatch(poly, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2 ))
ax.axis('scaled')
plt.show()

여기에 이미지 설명을 입력하십시오


정말 도움이 되겠지만, 여러 개의 폴리곤을 플롯 할 경우 for 루프에서이 작업을 수행 할 수 있습니까?
FaCoffee

예 문제 없음
유전자

나는 것으로 나타났습니다 descartes당신이 시도하고 사용하여 두 개의 인접한 줄거리에 두 개의 서로 다른 모양 파일을 플롯 경우 솔루션은 작업을하지 않는 fig, ax = plt.subplots(1,2,figsize=(15, 8))다음과 ax[0].add_patch(PolygonPatch(poly_geo, fc='#d3d3d3', ec='#000000', alpha=0, zorder=5))ax[1].add_patch(PolygonPatch(poly_geo, fc='#d3d3d3', ec='#000000', alpha=0, zorder=5)). 결과는 빈 이미지입니다. 어떤 생각?
FaCoffee

3

ldocao 외에도 FaCoffee 질문에 답변합니다. 고립 된 섬이 있고 동일한 기능의 일부인 경우 다음을 시도 할 수 있습니다.

import shapefile as shp
import matplotlib.pyplot as plt

sf = shp.Reader("test.shp")

plt.figure()
for shape in sf.shapeRecords():
    for i in range(len(shape.shape.parts)):
        i_start = shape.shape.parts[i]
        if i==len(shape.shape.parts)-1:
            i_end = len(shape.shape.points)
        else:
            i_end = shape.shape.parts[i+1]
        x = [i[0] for i in shape.shape.points[i_start:i_end]]
        y = [i[1] for i in shape.shape.points[i_start:i_end]]
        plt.plot(x,y)
plt.show()

이것은 나를 위해 작동합니다. 형상의 특성 "부품"은 형상 내에서 다른 형상의 시작 색인을 반환합니다.


2

이 답변 에서 논의 된 것처럼 geopandas 또는 pyshp를 사용하여 수행 할 수 있습니다 . Geopandas는 백엔드에서 matplotlib를 사용하여 플로팅합니다.


0

여전히 하나의 shapefile 모양에는 여러 부분이있을 수 있습니다. 이렇게하면 각 파트를 한 모양 내에서 개별적으로 플로팅합니다.

import matplotlib.pyplot as plt
import shapefile
import numpy as np

this_shapefile = shapefile.Reader(map_file_base) # whichever file
shape = this_shapefile.shape(i) # whichever shape
points = np.array(shape.points)

intervals = list(shape.parts) + [len(shape.points)]

ax = plt.gca()
ax.set_aspect(1)

for (i, j) in zip(intervals[:-1], intervals[1:]):
    ax.plot(*zip(*points[i:j]))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.