# Slope at a point on a Line (LineString) using Shapely and python

I've got a method for making cross-section points along a shapely `LineString` object that I'm not totally happy with.

My strategy is:

1. Create regular points every 50cm along a LineString
2. Create an offset point 1cm away from the 50.1cm point
3. Use these two points to find a slope
``````# Get 50cm spaced points
points = [linestr.interpolate(dist) for dist in np.arange(0, linestr.length, 0.5)]

# Get points at 50.1cm
_offsetpts = [linestr.interpolate(currDist+0.001) for currDist in np.arange(0, linestr.length, 0.5)]

# Use these two points to do rise/run and get a slope
slopes = [((points[idx].coords[0][1] - _offsetpts[idx].coords[0][1]) /
(points[idx].coords[0][0] - _offsetpts[idx].coords[0][0])) for idx, pt in enumerate(_offsetpts)]
``````

It works but it's not very elegant and I worry it will break for edge cases (like when 1 extra cm runs over the edge of the line)

Does anyone know a better way to get the slope of a line a known distance along a `LineString` object using python and shapely?

• What exactly is your goal? Jan 7, 2017 at 17:56

You don't need a second list of points to find the slopes

``````import itertools
# iterate by pairs of points
slopes = [(second.y-first.y)/(second.x-first.x)for first, second in itertools.izip(points, points[1:])]
``````

If you want the mean slope of the slopes

``````import numpy as np
def mean_slope(xs,ys):
m = (((np.mean(xs)*np.mean(ys)) - np.mean(xs*ys)) /((np.mean(xs)**2) - np.mean(xs*xs)))
return m
print mean_slope(slopes)
-2.2934712193638029
``````

You can also use NumPy or SciPy

``````x, y = zip(*[(pt.x, pt.y) for pt in points])
slope, intercept = np.polyfit(x,y,1)
print slope
-2.2934712193638029
from scipy import stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
print slope
-2.2934712193638029
``````

If the LineString is straight all the values of slopes = slope

If you want the slope between two point

``````first = points[5]
second = points[6]
print (second.y-first.y)/(second.x-first.x)
-2.2934712193638029 #straight line in my case
print np.polyfit([second.x,first.x],[second.y,first.y],1)[0]
-2.2934712193638029
print stats.linregress([second.x,first.x],[second.y,first.y])[0]
-2.2934712193638029
``````
• This is so close to what I need. I guess the only outstanding piece is that I don't have the two points. All I have is a line and a distance along that line. Maybe this is trivial and I'm missing something but is there a shapely way to find the line segment at distance `x` along a line segment? Do I need to break the LineString into pieces and test coordinate pairs until I find the one that contains the intersection? Jan 9, 2017 at 19:31
• – gene
Jan 9, 2017 at 19:41
• Thanks. Finally got to this and managed to get it working. Trouble was that it became really slow for lines with huge point counts. So I wrote a bisecting algorithm to locate it and it works pretty well. Jan 17, 2017 at 23:06