19

Is there an easy way to get the (x,y) values of a contour line that was plotted like this:

import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [1,2,3,4]
m = [[15,14,13,12],[14,12,10,8],[13,10,7,4],[12,8,4,0]]
cs = plt.contour(x,y,m, [9.5])
plt.show()
Cœur
  • 37,241
  • 25
  • 195
  • 267
Philipp der Rautenberg
  • 2,212
  • 3
  • 25
  • 39

2 Answers2

19

Look at the collections property of the returned ContourSet. In particular the get_paths() method of the first collection returns paired points making up each line segment.

cs.collections[0].get_paths()

To get a NumPy array of the coordinates, use the Path.vertices attribute.

p1 = cs.collections[0].get_paths()[0]  # grab the 1st path
coor_p1 = p1.vertices
Steven C. Howell
  • 16,902
  • 15
  • 72
  • 97
Mark
  • 106,305
  • 20
  • 172
  • 230
  • 1
    This is really useful, thanks! Do you know of any way of obtaining/interpolating equally spaced points on the contour curve? (the points returned in this way are not equally spaced) – Tropilio Jun 28 '19 at 16:48
1

Going through the collections and extracting the paths and vertices is not the most straight forward or fastest thing to do. The returned Contour object actually has attributes for the segments via cs.allsegs, which returns a nested list of shape [level][element][vertex_coord]:

num_levels = len(cs.allsegs)
num_element = len(cs.allsegs[0])  # in level 0
num_vertices = len(cs.allsegs[0][0])  # of element 0, in level 0
num_coord = len(cs.allsegs[0][0][0])  # of vertex 0, in element 0, in level 0

Hence the vertices of an all paths can be extracted as:

cs.allsegs[i][j]  # for element j, in level i

See reference: https://matplotlib.org/3.1.1/api/contour_api.html

RCCG
  • 175
  • 2
  • 7