numpy - Python: find contour lines from matplotlib.pyplot.contour() -
i'm trying find (but not draw!) contour lines data:
from pprint import pprint import matplotlib.pyplot z = [[0.350087, 0.0590954, 0.002165], [0.144522, 0.885409, 0.378515], [0.027956, 0.777996, 0.602663], [0.138367, 0.182499, 0.460879], [0.357434, 0.297271, 0.587715]] cn = matplotlib.pyplot.contour(z)
i know cn
contains contour lines want, can't seem them. i've tried several things:
print dir(cn) pprint(cn.collections[0]) print dir(cn.collections[0]) pprint(cn.collections[0].figure) print dir(cn.collections[0].figure)
to no avail. know cn
contourset
, , cn.collections
array of linecollection
s. think linecollection
array of line segments, can't figure out how extract segments.
my ultimate goal create kml file plots data on world map, , contours data well.
however, since of data points close together, , others far away, need actual polygons (linestrings) make contours, not rasterized image of contours.
i'm surprised qhull
doesn't this.
using mathematica's listcontourplot
, exporting svg works, want use open source.
i can't use well-known conrec algorithm because data isn't on mesh (there aren't multiple y values given x value, , vice versa).
the solution doesn't have python, have open source , runnable on linux.
you can vertices looping on collections , paths , using iter_segments()
method of matplotlib.path.path
.
here's function returns vertices set of nested lists of contour lines, contour sections , arrays of x,y vertices:
import numpy np def get_contour_verts(cn): contours = [] # each contour line cc in cn.collections: paths = [] # each separate section of contour line pp in cc.get_paths(): xy = [] # each segment of section vv in pp.iter_segments(): xy.append(vv[0]) paths.append(np.vstack(xy)) contours.append(paths) return contours
edit:
it's possible compute contours without plotting using undocumented matplotlib._cntr
c module:
from matplotlib import pyplot plt matplotlib import _cntr cntr z = np.array([[0.350087, 0.0590954, 0.002165], [0.144522, 0.885409, 0.378515], [0.027956, 0.777996, 0.602663], [0.138367, 0.182499, 0.460879], [0.357434, 0.297271, 0.587715]]) x, y = np.mgrid[:z.shape[0], :z.shape[1]] c = cntr.cntr(x, y, z) # trace contour @ z == 0.5 res = c.trace(0.5) # result list of arrays of vertices , path codes # (see docs matplotlib.path.path) nseg = len(res) // 2 segments, codes = res[:nseg], res[nseg:] fig, ax = plt.subplots(1, 1) img = ax.imshow(z.t, origin='lower') plt.colorbar(img) ax.hold(true) p = plt.polygon(segments[0], fill=false, color='w') ax.add_artist(p) plt.show()