Şekil dosyasını matplotlib ile çizin


15

Bir şekil dosyasını okumaya ve matplotlib kullanarak onu çizmeye çalışıyorum. İşte kod:

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

Ancak, çokgenlerimi bağlayan çizgiler alıyorum. Çokgenleri şekil dosyasında olacak şekilde nasıl çizebilirim. ArcGIS ile açıldığında arsa ve şekil dosyasının ekran görüntüleri.Kod Oluşturma Gerçek Dosya


Şekil dosyası okuyucusuna aşina değilim, ancak her şekli bileşen parçalarına ayırmadan dosyadaki tüm noktaları tek bir büyük listeye eklediğinizi söyleyebilirim. Her şekil noktasını eklediğiniz şekillerin büyük bir listesine ihtiyacınız var

Sağ. Şekilleri ayırmak için bir yol bulmak zorunda. Ama şu anda yapamadığım şey bu.
statBeginner

@DanPatterson Şekilleri ayırmayı başardıktan sonra aynı şekilde birden çok şeklin nasıl çizileceğini belirtebilir misiniz? Her şekil için plt.plot (listx, listy) kullanırsam, aynı şekli kullanmak yerine her seferinde yeni bir şekil oluşturmaya devam eder.
statBeginner

Yanıtlar:


10

Şekillerin nasıl toplanacağını size bırakacağım ama bu prensip

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

oh .. bunu nasıl özlediğimi merak ediyorum. Ben olsa farklı renklerde basılmış şekiller olsun. Bunu düzeltmek zorunda
kalacak

farklı şekiller nasıl elde edilir veya izole edilir?
FaCoffee

16

Gelecek referanslar için, yukarıdaki önerileri takip ettikten sonra geldiğim çözüm.

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

Ortaya çıkan rakam çok renkli olacak, ancak daha sonra, arsa anahtar kelimelerini ayarlamanız gerekiyor.


6
Bunun gereksiz bilgiler olabileceğini biliyorum, ancak konuya henüz aşina olmayanlar için şu pakete import shapefileatıfta bulunmak demek yararlı olurdu pyshp: pypi.python.org/pypi/pyshp
FaCoffee

Bir grup ada olduğunda bu sorun değil, çünkü bu noktalar anakaradaki noktalara çizgilerle bağlanacak ve OP'nin yayınladığı şeye benzer bir şey yaratacaktır.
FaCoffee

1
@FaCoffee, haklısın. Cevabım gis.stackexchange.com/a/309780/126618 bunu ele almalıdır.
Gus

9

Matplotlib yollarını ve yamaları kullanmanız gerekir ve Descartes işlevlerini kullanarak şekil dosyalarından çokgenleri çizmek için ayrılmış bir Python modülü vardır .

Pyshp (şekil dosyası) sahip olduğundan geo_interface ( Yeni geo_interface PyShp için kongre), bunu kullanabilirsiniz.

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)),)}

Sonuç, geometrinin GeoJSON temsilidir ve matplotlib / python kullanarak coğrafi verileri çizme çözümünü kullanabilirsiniz

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

resim açıklamasını buraya girin


Bu gerçekten yararlı, ancak çizmek için birden çok çokgen varsa bunu bir for döngüsü içinde yapabilir misiniz?
FaCoffee

Evet sorunsuz
gen

descartesİki bitişik alt grafiğe iki farklı şekil dosyası fig, ax = plt.subplots(1,2,figsize=(15, 8))ve sonra ax[0].add_patch(PolygonPatch(poly_geo, fc='#d3d3d3', ec='#000000', alpha=0, zorder=5))ve kullanarak kullanarak denerseniz ve çözümün işe yaramadığını fark ettim ax[1].add_patch(PolygonPatch(poly_geo, fc='#d3d3d3', ec='#000000', alpha=0, zorder=5)). Sonuç boş bir görüntüdür. Herhangi bir fikir?
FaCoffee

3

Ayrıca ldocao yanıtı ve FaCoffee sorusuna cevap. İzole adalarınız varsa ve bunlar aynı özelliğin bir parçasıysa, daha sonra deneyebilirsiniz:

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

Bu benim için işe yarıyor. Bir şeklin "parçaları", bir özellik içindeki farklı geometrilerin başlangıç ​​indekslerini döndürür.


2

Bu ele alındığı gibi geopandas veya pyshp kullanılarak yapılabilir bu cevap . Geopandalar çizim için arka ucunda matplotlib kullanırlar.


0

Yine de, bir şekil dosyası şeklinde, birden fazla parça olabilir. Bu, her bir parçayı ayrı bir şekilde çizecektir.

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]))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.