พล็อต shapefile ด้วย matplotlib


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

อย่างไรก็ตามฉันได้รับสายเชื่อมต่อรูปหลายเหลี่ยมของฉัน ฉันจะวาดรูปหลายเหลี่ยมแบบที่เป็นในไฟล์ได้อย่างไร นี่คือภาพหน้าจอของพล็อตและรูปร่างไฟล์เมื่อเปิดด้วย 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

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 เส้นทางและแพทช์และมีโมดูลหลามที่ทุ่มเทให้กับพล็อตจากรูปหลายเหลี่ยม shapefiles ใช้เหล่านี้ฟังก์ชั่นDescartes

เนื่องจาก Pyshp (shapefile) มีรูปแบบgeo_interface ( ใหม่geo_interfaceสำหรับ PyShp ) คุณสามารถใช้มันได้

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

ป้อนคำอธิบายรูปภาพที่นี่


มีประโยชน์จริง ๆ แต่คุณสามารถทำเช่นนี้ในการวนรอบถ้าคุณมีรูปหลายเหลี่ยมหลายที่จะลงจุด
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()

มันทำให้มันใช้ได้สำหรับฉัน "ชิ้นส่วน" ที่เหมาะสมของรูปร่างส่งคืนดัชนีเริ่มต้นของรูปทรงเรขาคณิตของ differents ภายในคุณลักษณะ



0

ยังคงอยู่ในรูปแบบไฟล์เดียวอาจมีหลายส่วน สิ่งนี้จะลงจุดแต่ละส่วนในรูปร่างเดียวแยกจากกัน

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.