{"record":{"id":"57b582a59334f5d7","repo":"pola-rs/polars","slug":"cannot-use-plot-hist-when-series-name-is-count","errorCode":null,"errorMessage":"cannot use `plot.hist` when Series name is `'count()'`","messagePattern":"cannot use `plot\\.hist` when Series name is `'count\\(\\)'`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/plotting.py","lineNumber":68,"sourceCode":"        .. versionchanged:: 1.6.0\n            In prior versions of Polars, HvPlot was the plotting backend. If you would\n            like to restore the previous plotting functionality, all you need to do\n            is add `import hvplot.polars` at the top of your script and replace\n            `df.plot` with `df.hvplot`.\n\n        Parameters\n        ----------\n        **kwargs\n            Additional arguments and keyword arguments passed to Altair.\n\n        Examples\n        --------\n        >>> s = pl.Series(\"price\", [1, 3, 3, 3, 5, 2, 6, 5, 5, 5, 7])\n        >>> s.plot.hist()  # doctest: +SKIP\n        \"\"\"  # noqa: W505\n        if self._series_name == \"count()\":\n            msg = \"cannot use `plot.hist` when Series name is `'count()'`\"\n            raise ValueError(msg)\n        encodings: Encodings = {\n            \"x\": alt.X(f\"{self._series_name}:Q\", bin=True),\n            \"y\": \"count()\",\n        }\n        return (\n            alt.Chart(self._df)\n            .mark_bar(tooltip=True)\n            .encode(**encodings, **kwargs)\n            .interactive()\n        )\n\n    def kde(\n        self,\n        /,\n        **kwargs: Unpack[EncodeKwds],\n    ) -> alt.Chart:\n        \"\"\"\n        Draw kernel density estimate plot.","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/series/plotting.py#L50-L86","documentation":"Raised by Series.plot.hist (py-polars/src/polars/series/plotting.py:68) when the Series is literally named 'count()'. The histogram hardcodes y=\"count()\" as its Altair aggregation encoding, so a column with that exact name would collide with the aggregation field and produce a broken chart; polars therefore refuses with ValueError up front.","triggerScenarios":"pl.Series(\"count()\", [...]).plot.hist(), or plotting a column that was produced by an aggregation and renamed to 'count()' — e.g. df.group_by(\"a\").len().rename({\"len\": \"count()\"})[\"count()\"].plot.hist().","commonSituations":"Chaining value_counts()/group_by output into a histogram plot, or data loaded from sources where the column name happens to be 'count()'. This is a name-collision guard, not a data problem.","solutions":["Rename the Series before plotting: s.rename(\"price\").plot.hist() (rename returns a new Series)","Or fix the name upstream where the column was created, so downstream plotting code never sees 'count()'","If the name comes from external data, add a rename step in your ingestion pipeline"],"exampleFix":"# before\ns = pl.Series(\"count()\", [1, 3, 3, 5])\ns.plot.hist()  # ValueError\n\n# after\ns.rename(\"price\").plot.hist()","handlingStrategy":"validation","validationCode":"PLOT_RESERVED_NAMES = {\"count()\"}\nname = \"count()\" if s.name in PLOT_RESERVED_NAMES else s.name  # detect\ns_safe = s.rename(\"value\") if s.name in PLOT_RESERVED_NAMES else s\ns_safe.plot.hist()","typeGuard":null,"tryCatchPattern":"try:\n    chart = s.plot.hist()\nexcept ValueError as e:\n    if \"'count()'\" in str(e):\n        chart = s.rename(\"value\").plot.hist()\n    else:\n        raise","preventionTips":["Rename aggregation-produced columns (count()/len) to descriptive names before plotting","Wrap plotting in a helper that renames reserved chart names ('count()', 'density', 'index')"],"tags":["polars","plotting","altair","valueerror","naming"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}