{"record":{"id":"9b5cd8517ac6d913","repo":"pola-rs/polars","slug":"cannot-use-plot-kde-when-series-name-is-densit","errorCode":null,"errorMessage":"cannot use `plot.kde` when Series name is `'density'`","messagePattern":"cannot use `plot\\.kde` when Series name is `'density'`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/plotting.py","lineNumber":114,"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 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.kde()  # doctest: +SKIP\n        \"\"\"  # noqa: W505\n        if self._series_name == \"density\":\n            msg = \"cannot use `plot.kde` when Series name is `'density'`\"\n            raise ValueError(msg)\n        encodings: Encodings = {\"x\": self._series_name, \"y\": \"density:Q\"}\n        return (\n            alt.Chart(self._df)\n            .transform_density(self._series_name, as_=[self._series_name, \"density\"])\n            .mark_area(tooltip=True)\n            .encode(**encodings, **kwargs)\n            .interactive()\n        )\n\n    def line(\n        self,\n        /,\n        **kwargs: Unpack[EncodeKwds],\n    ) -> alt.Chart:\n        \"\"\"\n        Draw line plot.\n\n        Polars does not implement plotting logic itself but instead defers to","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/series/plotting.py#L96-L132","documentation":"Raised by Series.plot.kde (py-polars/src/polars/series/plotting.py:114) when the Series is named 'density'. The KDE chart calls Altair's transform_density(..., as_=[name, \"density\"]), which creates a derived column named 'density' for the y axis; a Series already named 'density' would collide with that derived field, so polars raises ValueError before building the chart.","triggerScenarios":"pl.Series(\"density\", [...]).plot.kde(), or any KDE plot on a column literally named 'density' — typically the output of a previous density estimation or a stats table.","commonSituations":"Plotting kernel-density results stored in a 'density' column, or ingested datasets that already use 'density' as a field name. Pure name-collision guard; the data itself is fine.","solutions":["Rename before plotting: s.rename(\"value\").plot.kde()","Rename the column upstream in the DataFrame: df.rename({\"density\": \"density_est\"})[\"density_est\"].plot.kde()","Standardize ingestion to avoid reserved-ish chart field names if you plot often"],"exampleFix":"# before\ns = pl.Series(\"density\", [1.0, 2.2, 3.1])\ns.plot.kde()  # ValueError\n\n# after\ns.rename(\"value\").plot.kde()","handlingStrategy":"validation","validationCode":"s_safe = s.rename(\"value\") if s.name == \"density\" else s\ns_safe.plot.kde()","typeGuard":null,"tryCatchPattern":"try:\n    chart = s.plot.kde()\nexcept ValueError as e:\n    if \"'density'\" in str(e):\n        chart = s.rename(\"value\").plot.kde()\n    else:\n        raise","preventionTips":["Avoid 'density' as a column name when you plan to use plot.kde","Rename derived statistics columns to descriptive names before visualization"],"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"}