{"record":{"id":"1ca1e104b89dd1f5","repo":"matplotlib/matplotlib","slug":"must-be-same-number-of-segments-as-levels","errorCode":null,"errorMessage":"must be same number of segments as levels","messagePattern":"must be same number of segments as levels","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/contour.py","lineNumber":916,"sourceCode":"        Must set self.levels, self.zmin and self.zmax, and update Axes limits.\n        \"\"\"\n        self.levels = args[0]\n        allsegs = args[1]\n        allkinds = args[2] if len(args) > 2 else None\n        self.zmax = np.max(self.levels)\n        self.zmin = np.min(self.levels)\n\n        if allkinds is None:\n            allkinds = [[None] * len(segs) for segs in allsegs]\n\n        # Check lengths of levels and allsegs.\n        if self.filled:\n            if len(allsegs) != len(self.levels) - 1:\n                raise ValueError('must be one less number of segments as '\n                                 'levels')\n        else:\n            if len(allsegs) != len(self.levels):\n                raise ValueError('must be same number of segments as levels')\n\n        # Check length of allkinds.\n        if len(allkinds) != len(allsegs):\n            raise ValueError('allkinds has different length to allsegs')\n\n        # Determine x, y bounds and update axes data limits.\n        flatseglist = [s for seg in allsegs for s in seg]\n        points = np.concatenate(flatseglist, axis=0)\n        self._mins = points.min(axis=0)\n        self._maxs = points.max(axis=0)\n\n        # Each entry in (allsegs, allkinds) is a list of (segs, kinds): segs is a list\n        # of (N, 2) arrays of xy coordinates, kinds is a list of arrays of corresponding\n        # pathcodes.  However, kinds can also be None; in which case all paths in that\n        # list are codeless (this case is normalized above).  These lists are used to\n        # construct paths, which then get concatenated.\n        self._paths = [Path.make_compound_path(*map(Path, segs, kinds))\n                       for segs, kinds in zip(allsegs, allkinds)]","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/contour.py#L898-L934","documentation":"On the manual-construction path (ContourSet(levels, allsegs, allkinds)), unfilled line contours require exactly one segment list per level: len(allsegs) == len(levels). Unlike the filled case, line contours get a segment list for every level, including levels with no contour lines (represented by an empty list). ValueError is raised on any other count.","triggerScenarios":"Building ContourSet with line-contour geometry that dropped empty levels (e.g. filtered out levels where no line was found); passing band geometry (len(levels)-1 lists, correct only for filled=True) while leaving filled=False; off-by-one errors when slicing cached geometry.","commonSituations":"Replaying serialized contour geometry; mixing up filled and line geometry conventions when switching between contourf output and contour; trimming 'empty' segment lists during caching to save space.","solutions":["Supply exactly len(levels) segment lists; keep empty lists [] for levels with no geometry.","If the geometry was computed for filled bands, regenerate it as lines (contour_generator(...).lines(levels)) or construct with filled=True.","Recompute rather than hand-trimming: len(allsegs) must equal len(levels) at construction time.","Add a pre-check: assert len(allsegs) == len(levels) before constructing."],"exampleFix":"# before\nsegs = [s for s in line_segs if s]   # accidentally dropped empties\nContourSet(ax, levels, segs)         # len mismatch -> ValueError\n\n# after\nContourSet(ax, levels, line_segs)   # keep one (possibly empty) list per level","handlingStrategy":"validation","validationCode":"assert len(allsegs) == len(levels), \\\n    f'{len(allsegs)} segment lists vs {len(levels)} levels'","typeGuard":null,"tryCatchPattern":"try:\n    ContourSet(ax, levels, allsegs)\nexcept ValueError:\n    allsegs = [allsegs[i] if i < len(allsegs) else [] for i in range(len(levels))]\n    ContourSet(ax, levels, allsegs)","preventionTips":["Keep empty [] entries for levels that produced no lines.","Store levels alongside segment lists so they cannot drift apart.","Re-derive geometry with gen.lines(levels) rather than editing cached lists."],"tags":["matplotlib","contour","contourset","levels","valueerror"],"backgroundTag":"array-length-mismatch","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}