# Write shp into python and fill in the attribute table

I am struggling to create a shp and I want it to writes records on the attribute table. I can create the shp but I can not fill in with the correct records. I import an Excel file, that contains the fields "code", "x_Start", "y_Start", "x_Finish", "y_Finish" and I want the field 'code' on the shp table.

Here is the code:

import pandas as pd
import geopandas as gpd
import requests
from shapely.geometry import Point

#import excel
import requests

#then I create trajectories through an API and I get a list.

a = list(zip(*[list(df['x_S']), list(df['y_S']), list(df['x_F']), list(df['y_F'])]))
#print (a)
b = [bb for bb in [create_trajectory(coords) for coords in a] if not bb is None]
dg = pd.DataFrame(b)
dg

#I can create the shp from dg but I can't know how to fill in the attribute with th df. Ν.Β. that I do not get the same number routes as I give on excel file.

import shapefile

# Create a polyline shapefile writer
with shapefile.Writer("shapefiles/test/routeNI6") as w:
#w = shapefile.Writer(shapefile.POLYLINE)

w.field("NAME", "C", "40")

#lines = []
for i, row in df.iterrows():
w.record(df.code)

w.line([list(row.dropna())])


I want to add only the 'code' records. and here are the errors that I get

TypeError                                 Traceback (most recent call last)
<ipython-input-115-04aa2ea41a9f> in <module>
21
---> 22         w.line([list(row.dropna())])

~\Anaconda3\lib\site-packages\shapefile.py in line(self, lines)
1670         shapeType = POLYLINE
-> 1671         self._shapeparts(parts=lines, shapeType=shapeType)
1672

~\Anaconda3\lib\site-packages\shapefile.py in _shapeparts(self, parts, shapeType)
1756                 if not isinstance(point, list):
-> 1757                     point = list(point)
1758                 polyShape.points.append(point)

TypeError: 'float' object is not iterable

During handling of the above exception, another exception occurred:

ShapefileException                        Traceback (most recent call last)
<ipython-input-115-04aa2ea41a9f> in <module>
20         #lines.append(list(row))
21
---> 22         w.line([list(row.dropna())])

~\Anaconda3\lib\site-packages\shapefile.py in __exit__(self, exc_type, exc_val, exc_tb)
1099         Exit phase of context manager, finish writing and close the files.
1100         """
-> 1101         self.close()
1102
1103     def __del__(self):

~\Anaconda3\lib\site-packages\shapefile.py in close(self)
1120                 raise ShapefileException("When saving both the dbf and shp file, "
1121                                          "the number of records (%s) must correspond "
-> 1122                                          "with the number of shapes (%s)" % (self.recNum, self.shpNum))
1123         # Fill in the blank headers
1124         if self.shp and shp_open:

ShapefileException: When saving both the dbf and shp file, the number of records (1) must correspond with the number of shapes (0)


I have added the libraries that I use. Actually, I have some couple of thousand polylines. This code is a part of the whole code.

I import the excel file as df and then I create trajectories as dg. So I want to create a shp with features from the dg and to fill in the attribute from df. I hope it helps. I am sorry for the inconvenience but I am quite fresh.

• and what exactly is the error you get? – zwnk Jul 30 at 20:57
• first of all, if you want to have NAME, X and Y seperated you need to add 3 fields: w.field("NAME", "C", "40") w.field('X', 'N', decimal=10) w.field('Y', 'N', decimal=10) assuming your excel input has NAME, X and Y in one line, you need to split them and insert them into the different fields. – zwnk Jul 30 at 21:05
• the second error occures because your shapefile dosn't contain a geometry. what is w.line([list(row.dropna())]) doing? – zwnk Jul 30 at 21:56

Your code has several issues. First one, 'read_excel' method belongs pandas library and this is not reflected in your question. Additionally, you need to define how many features has your shapefile.POLYLINE. Assuming a polyline with two features, I created a xls file named NI.xls with field code and only two records. So, I also need to define points for each feature:

[-40.5, -20.666],[-39.849998, -18.700001]
[-39.849998, -18.700001],[-39.816002, -19.6]


For avoiding projection issues, I assumed the data for EPSG 4326.

So, with all above assumptions, my code looks as follow:

import shapefile
import pandas as pd

w = shapefile.Writer(shapefile.POLYLINE)
w.line(parts=[[[-40.5, -20.666],[-39.849998, -18.700001]]])
w.poly(parts=[[[-39.849998, -18.700001],[-39.816002, -19.6]]], shapeType=shapefile.POLYLINE)
w.field('code','C','40')

for i, row in df.iterrows():
w.record(str(row[0]))

filename = "/home/zeito/pyqgis_data/routeNI7"

w.save(filename)

prj = open("%s.prj" % filename, "w")
epsg = 'GEOGCS["WGS 84",'
epsg += 'DATUM["WGS_1984",'
epsg += 'SPHEROID["WGS 84",6378137,298.257223563]]'
epsg += ',PRIMEM["Greenwich",0],'
epsg += 'UNIT["degree",0.0174532925199433]]'
prj.write(epsg)
prj.close()


After running it at Python Console, I got expected result:

Editing Note:

By using osr osgeo python module, it is easier to define shapefile projection from EPSG:

import shapefile
import pandas as pd
from osgeo import osr

w = shapefile.Writer(shapefile.POLYLINE)
w.line(parts=[[[-40.5, -20.666],[-39.849998, -18.700001]]])
w.poly(parts=[[[-39.849998, -18.700001],[-39.816002, -19.6]]], shapeType=shapefile.POLYLINE)
w.field('code','C','40')

for i, row in df.iterrows():
w.record(str(row[0]))

filename = "/home/zeito/pyqgis_data/routeNI7"

w.save(filename)

add_prj = open("%s.prj" % filename, "w")

proj = osr.SpatialReference()
proj.ImportFromEPSG(4326)
epsg = proj.ExportToWkt()


• I tried my code out in Windows without any success. I searched for possibles issues and it is probably due a bug in pyshp module (bug is referred in several comments). This line: w=shapefile.Writer(shapefile.POLYLINE) produces an unexpected AttributeError. This error is not produced in old python 2.7 with old versions of pyshp. I suggest to use another module instead pyshp. – xunilk Aug 2 at 2:38