{"record":{"id":"88e3a8633f545111","repo":"matplotlib/matplotlib","slug":"the-rows-of-x-must-be-equal","errorCode":null,"errorMessage":"The rows of 'x' must be equal","messagePattern":"The rows of 'x' must be equal","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/streamplot.py","lineNumber":378,"sourceCode":"        if not self.grid.within_grid(xg, yg):\n            raise InvalidIndexError\n        xm, ym = self.grid2mask(xg, yg)\n        self.mask._update_trajectory(xm, ym, broken_streamlines)\n\n    def undo_trajectory(self):\n        self.mask._undo_trajectory()\n\n\nclass Grid:\n    \"\"\"Grid of data.\"\"\"\n    def __init__(self, x, y):\n\n        if np.ndim(x) == 1:\n            pass\n        elif np.ndim(x) == 2:\n            x_row = x[0]\n            if not np.allclose(x_row, x):\n                raise ValueError(\"The rows of 'x' must be equal\")\n            x = x_row\n        else:\n            raise ValueError(\"'x' can have at maximum 2 dimensions\")\n\n        if np.ndim(y) == 1:\n            pass\n        elif np.ndim(y) == 2:\n            yt = np.transpose(y)  # Also works for nested lists.\n            y_col = yt[0]\n            if not np.allclose(y_col, yt):\n                raise ValueError(\"The columns of 'y' must be equal\")\n            y = y_col\n        else:\n            raise ValueError(\"'y' can have at maximum 2 dimensions\")\n\n        if not (np.diff(x) > 0).all():\n            raise ValueError(\"'x' must be strictly increasing\")\n        if not (np.diff(y) > 0).all():","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/streamplot.py#L360-L396","documentation":"streamplot's Grid accepts 1D coordinate arrays, or 2D arrays equivalent to np.meshgrid(x_1d, y_1d): every row of x must be identical (and every column of y). If the rows of a 2D x differ, the coordinates do not describe a regular Cartesian grid and this ValueError is raised. The near-universal cause is a meshgrid built with indexing='ij', or x and y passed in swapped order.","triggerScenarios":"X, Y = np.meshgrid(x, y, indexing='ij') where rows of X vary; passing np.meshgrid(y, x) output in the wrong order; feeding curvilinear coordinates from unstructured grids.","commonSituations":"Numerical codes written with matrix (row-major) indexing; porting plotting code between matplotlib and libraries that assume 'ij'-shaped grids.","solutions":["Pass 1D coordinate arrays: ax.streamplot(x_1d, y_1d, u, v)","For 2D coordinates use default indexing: X, Y = np.meshgrid(x, y), whose rows of X are constant","For 'ij'-shaped data, transpose the 2D coordinate arrays and u, v before calling"],"exampleFix":"# before\nX, Y = np.meshgrid(x, y, indexing='ij')\nax.streamplot(X, Y, u, v)  # ValueError: rows of 'x' not equal\n\n# after\nax.streamplot(x, y, u.T, v.T)  # 1D coords, 'xy' convention","handlingStrategy":"validation","validationCode":"x, y = np.asarray(x), np.asarray(y)\nif x.ndim == 2 and not np.allclose(x, x[0]):\n    x, y, u, v = x.T, y.T, u.T, v.T  # input was 'ij'-gridded\nax.streamplot(x, y, u, v)","typeGuard":"def is_xy_meshgrid(x) -> bool:\n    x = np.asarray(x)\n    return x.ndim == 1 or np.allclose(x, x[0])","tryCatchPattern":null,"preventionTips":["Pass 1D coordinate arrays to streamplot whenever possible","Use np.meshgrid(x, y) with default indexing when 2D grids are required","Keep one mesh convention per codebase; transpose at the ingestion boundary for 'ij' data"],"tags":["matplotlib","streamplot","numpy","meshgrid"],"backgroundTag":"meshgrid-axis-mismatch","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}