{"record":{"id":"87bc7eb5c9182114","repo":"matplotlib/matplotlib","slug":"the-shapes-of-flows-np-shape-flows-and-orien","errorCode":null,"errorMessage":"The shapes of 'flows' {np.shape(flows)} and 'orientations' {np.shape(orientations)} are incompatible","messagePattern":"The shapes of 'flows' (.+?) and 'orientations' (.+?) are incompatible","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/sankey.py","lineNumber":449,"sourceCode":"\n        See Also\n        --------\n        Sankey.finish\n        \"\"\"\n        # Check and preprocess the arguments.\n        flows = np.array([1.0, -1.0]) if flows is None else np.array(flows)\n        n = flows.shape[0]  # Number of flows\n        if rotation is None:\n            rotation = 0\n        else:\n            # In the code below, angles are expressed in deg/90.\n            rotation /= 90.0\n        if orientations is None:\n            orientations = 0\n        try:\n            orientations = np.broadcast_to(orientations, n)\n        except ValueError:\n            raise ValueError(\n                f\"The shapes of 'flows' {np.shape(flows)} and 'orientations' \"\n                f\"{np.shape(orientations)} are incompatible\"\n            ) from None\n        try:\n            labels = np.broadcast_to(labels, n)\n        except ValueError:\n            raise ValueError(\n                f\"The shapes of 'flows' {np.shape(flows)} and 'labels' \"\n                f\"{np.shape(labels)} are incompatible\"\n            ) from None\n        if trunklength < 0:\n            raise ValueError(\n                \"'trunklength' is negative, which is not allowed because it \"\n                \"would cause poor layout\")\n        if abs(np.sum(flows)) > self.tolerance:\n            _log.info(\"The sum of the flows is nonzero (%f; patchlabel=%r); \"\n                      \"is the system not at steady state?\",\n                      np.sum(flows), patchlabel)","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/sankey.py#L431-L467","documentation":"In Sankey.add(), 'orientations' (values -1/0/1 saying whether each flow goes to the bottom, right/left, or top) is normalized with np.broadcast_to(orientations, n) where n = len(flows). A scalar broadcasts to all flows, but an array whose length is neither 1 nor n fails the broadcast, and sankey.py:447-452 re-raises that failure as a ValueError naming the two shapes. So the error means your orientations list has a different length than your flows list.","triggerScenarios":"sankey.add(flows=[1, -1, 0.5], orientations=[1, -1]) — 3 flows, 2 orientations; passing orientations as a 2-D array like [[1, -1]]; adding or removing a flow value without updating the orientations list.","commonSituations":"Editing a data-driven flows list (e.g. from a DataFrame column) while orientations stays hard-coded; passing df['direction'].tolist() where the DataFrame was filtered independently of the flows column.","solutions":["Make len(orientations) == len(flows), with each entry in {-1, 0, 1}.","If all flows share one orientation, pass a scalar (orientations=1) and let broadcasting apply it.","Build both lists from the same source rows so they cannot diverge (e.g. zip one DataFrame iteration)."],"exampleFix":"# before\nsankey.add(flows=[1, -1, 0.5], orientations=[1, -1])\n\n# after\nsankey.add(flows=[1, -1, 0.5], orientations=[1, -1, 0])\n# or all the same: sankey.add(flows=[1, -1, 0.5], orientations=1)","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef check_add_shapes(flows, orientations, labels):\n    n = len(flows)\n    if np.size(orientations) not in (1, n):\n        raise ValueError(f'orientations has {np.size(orientations)} entries, flows has {n}')\n    if np.size(labels) not in (1, n):\n        raise ValueError(f'labels has {np.size(labels)} entries, flows has {n}')\n\ncheck_add_shapes(flows, orientations, labels)\nsankey.add(flows=flows, orientations=orientations, labels=labels)","typeGuard":null,"tryCatchPattern":"try:\n    sankey.add(flows=flows, orientations=orientations)\nexcept ValueError as e:\n    if 'incompatible' in str(e):\n        # log shapes to find the diverging source\n        raise ValueError(f'{e}; flows={np.shape(flows)}') from None\n    raise","preventionTips":["Derive flows, orientations, and labels from the same row iteration so they stay aligned.","Prefer a scalar orientations value when all flows share a direction.","Add a shape-check helper in test suites for data-pipeline code feeding Sankey."],"tags":["matplotlib","sankey","valueerror","numpy-broadcast","shape-mismatch"],"backgroundTag":"array-shape-mismatch","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}