{"id":14341342,"url":"https://github.com/alceal/plotlars","last_synced_at":"2025-08-19T23:33:48.936Z","repository":{"id":254707124,"uuid":"834450393","full_name":"alceal/plotlars","owner":"alceal","description":"Plotlars is a Rust library designed to facilitate the integration between the Polars data analysis library and visualization libraries.","archived":false,"fork":false,"pushed_at":"2024-08-25T14:03:47.000Z","size":70,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-25T14:58:03.541Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alceal.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-27T09:58:09.000Z","updated_at":"2024-08-25T14:58:21.547Z","dependencies_parsed_at":"2024-08-25T14:58:12.492Z","dependency_job_id":"6450b86e-860e-48dd-aa75-e1d295b0d525","html_url":"https://github.com/alceal/plotlars","commit_stats":null,"previous_names":["alceal/plotlars"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alceal%2Fplotlars","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alceal%2Fplotlars/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alceal%2Fplotlars/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alceal%2Fplotlars/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alceal","download_url":"https://codeload.github.com/alceal/plotlars/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":217019189,"owners_count":16112401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-26T14:01:12.830Z","updated_at":"2025-08-19T23:33:48.924Z","avatar_url":"https://github.com/alceal.png","language":"Rust","readme":"# Plotlars\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://crates.io/crates/plotlars\"\u003e\n    \u003cimg alt=\"Crates.io\" src=\"https://img.shields.io/crates/v/plotlars.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://docs.rs/plotlars\"\u003e\n    \u003cimg alt=\"docs.rs\" src=\"https://img.shields.io/docsrs/plotlars\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/your-repo/plotlars/blob/main/LICENSE\"\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-blue.svg\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nPlotlars is a versatile Rust library that acts as a wrapper around the Plotly\ncrate, bridging the gap between the powerful Polars data analysis library and\nPlotly. It simplifies the process of creating visualizations from data frames,\nallowing developers to focus on data insights rather than the intricacies of\nplot creation.\n\n## Implemented Plots Overview\n\n| Plot | Example | Plot | Example | Plot | Example |\n|------|:---------:|------|:---------:|------|:---------:|\n| [Array 2D](https://docs.rs/plotlars/latest/plotlars/struct.Array2dPlot.html) | \u003cimg src=\"https://imgur.com/LMrqAaT.png\" width=\"100\" height=\"100\"\u003e | [Bar Plot](https://docs.rs/plotlars/latest/plotlars/struct.BarPlot.html) | \u003cimg src=\"https://imgur.com/2alZlO5.png\" width=\"100\" height=\"100\"\u003e | [Box Plot](https://docs.rs/plotlars/latest/plotlars/struct.BoxPlot.html) | \u003cimg src=\"https://imgur.com/uj1LY90.png\" width=\"100\" height=\"100\"\u003e |\n| [Candlestick](https://docs.rs/plotlars/latest/plotlars/struct.CandlestickPlot.html) | \u003cimg src=\"https://imgur.com/z5s2zm7.png\" width=\"100\" height=\"100\"\u003e | [Contour Plot](https://docs.rs/plotlars/latest/plotlars/struct.ContourPlot.html) | \u003cimg src=\"https://imgur.com/VWgxHC8.png\" width=\"100\" height=\"100\"\u003e | [Density Mapbox](https://docs.rs/plotlars/latest/plotlars/struct.DensityMapbox.html) | \u003cimg src=\"https://imgur.com/6sHke2h.png\" width=\"100\" height=\"100\"\u003e |\n| [Heat Map](https://docs.rs/plotlars/latest/plotlars/struct.HeatMap.html) | \u003cimg src=\"https://imgur.com/5uFih4M.png\" width=\"100\" height=\"100\"\u003e | [Histogram](https://docs.rs/plotlars/latest/plotlars/struct.Histogram.html) | \u003cimg src=\"https://imgur.com/w2oiuIo.png\" width=\"100\" height=\"100\"\u003e | [Image](https://docs.rs/plotlars/latest/plotlars/struct.Image.html) | \u003cimg src=\"https://imgur.com/PAtdaHj.png\" width=\"100\" height=\"100\"\u003e |\n| [Line Plot](https://docs.rs/plotlars/latest/plotlars/struct.LinePlot.html) | \u003cimg src=\"https://imgur.com/PaXG300.png\" width=\"100\" height=\"100\"\u003e | [Mesh3D](https://docs.rs/plotlars/latest/plotlars/struct.Mesh3D.html) | \u003cimg src=\"https://imgur.com/lKI23dJ.png\" width=\"100\" height=\"100\"\u003e | [OHLC](https://docs.rs/plotlars/latest/plotlars/struct.OhlcPlot.html) | \u003cimg src=\"https://imgur.com/jZM3bGq.png\" width=\"100\" height=\"100\"\u003e |\n| [Pie Chart](https://docs.rs/plotlars/latest/plotlars/struct.PieChart.html) | \u003cimg src=\"https://imgur.com/jE70hYS.png\" width=\"100\" height=\"100\"\u003e | [Sankey Diagram](https://docs.rs/plotlars/latest/plotlars/struct.SankeyDiagram.html) | \u003cimg src=\"https://imgur.com/jvAew8u.png\" width=\"100\" height=\"100\"\u003e | [Scatter 3D Plot](https://docs.rs/plotlars/latest/plotlars/struct.Scatter3dPlot.html) | \u003cimg src=\"https://imgur.com/WYTQxHA.png\" width=\"100\" height=\"100\"\u003e |\n| [Scatter Geo](https://docs.rs/plotlars/latest/plotlars/struct.ScatterGeo.html) | \u003cimg src=\"https://imgur.com/tYHM5FH.png\" width=\"100\" height=\"100\"\u003e | [Scatter Map](https://docs.rs/plotlars/latest/plotlars/struct.ScatterMap.html) | \u003cimg src=\"https://imgur.com/8MCjVOd.png\" width=\"100\" height=\"100\"\u003e | [Scatter Plot](https://docs.rs/plotlars/latest/plotlars/struct.ScatterPlot.html) | \u003cimg src=\"https://imgur.com/9jfO8RU.png\" width=\"100\" height=\"100\"\u003e |\n| [Scatter Polar](https://docs.rs/plotlars/latest/plotlars/struct.ScatterPolar.html) | \u003cimg src=\"https://imgur.com/fJiNlqn.png\" width=\"100\" height=\"100\"\u003e | [Surface Plot](https://docs.rs/plotlars/latest/plotlars/struct.SurfacePlot.html) | \u003cimg src=\"https://imgur.com/tdVte4l.png\" width=\"100\" height=\"100\"\u003e | [Table](https://docs.rs/plotlars/latest/plotlars/struct.Table.html) | \u003cimg src=\"https://imgur.com/50lrDKK.png\" width=\"100\" height=\"100\"\u003e |\n| [Time Series](https://docs.rs/plotlars/latest/plotlars/struct.TimeSeriesPlot.html) | \u003cimg src=\"https://imgur.com/hL27Xcn.png\" width=\"100\" height=\"100\"\u003e | | | | |\n\n## Motivation\n\nThe creation of Plotlars was driven by the need to simplify the process of\ncreating complex plots in Rust, particularly when working with the powerful\nPolars data manipulation library. Generating visualizations often requires\nextensive boilerplate code and deep knowledge of both the plotting library\n(Plotly) and the data structure. This complexity can be a significant hurdle,\nespecially for users who need to focus on analyzing and interpreting data rather\n than wrestling with intricate plotting logic.\n\nTo illustrate this, consider the following example where a scatter plot is\ncreated **without Plotlars**:\n\n```rust\nuse plotly::{\n    common::*,\n    layout::*,\n    Plot,\n    Scatter,\n};\n\nuse polars::prelude::*;\n\nfn main() {\n    let dataset = LazyCsvReader::new(PlPath::new(\"data/penguins.csv\"))\n        .finish().unwrap()\n        .select([\n            col(\"species\"),\n            col(\"flipper_length_mm\").cast(DataType::Int16),\n            col(\"body_mass_g\").cast(DataType::Int16),\n        ])\n        .collect().unwrap();\n\n    let group_column = \"species\";\n    let x = \"body_mass_g\";\n    let y = \"flipper_length_mm\";\n\n    let groups = dataset\n        .column(group_column).unwrap()\n        .unique().unwrap();\n\n    let layout = Layout::new()\n        .title(Title::with_text(\"Penguin Flipper Length vs Body Mass\"))\n        .x_axis(Axis::new().title(Title::with_text(\"Body Mass (g)\")))\n        .y_axis(Axis::new().title(Title::with_text(\"Flipper Length (mm)\")))\n        .legend(Legend::new().title(Title::with_text(\"Species\")));\n\n    let mut plot = Plot::new();\n    plot.set_layout(layout);\n\n    let groups_str = groups.str().unwrap();\n\n    for group in groups_str.into_iter() {\n        let group = group.unwrap();\n\n        let data = dataset\n            .clone()\n            .lazy()\n            .filter(col(group_column).eq(lit(group)))\n            .collect().unwrap();\n\n        let x = data\n            .column(x).unwrap()\n            .i16().unwrap()\n            .to_vec();\n\n        let y = data\n            .column(y).unwrap()\n            .i16().unwrap()\n            .to_vec();\n\n        let trace = Scatter::default()\n            .x(x)\n            .y(y)\n            .name(group)\n            .mode(Mode::Markers)\n            .marker(Marker::new().size(10).opacity(0.5));\n\n        plot.add_trace(trace);\n    }\n\n    plot.show();\n}\n```\n\nIn this example, creating a scatter plot involves writing substantial code to\nmanually handle the data and configure the plot, including grouping the data by\ncategory and setting up the plot layout.\n\nNow, compare that to the same plot created **using Plotlars**:\n\n```rust\nuse plotlars::{\n    ScatterPlot,\n    Plot,\n    Rgb,\n};\n\nuse polars::prelude::*;\n\nfn main() {\n    let dataset = LazyCsvReader::new(PlPath::new(\"data/penguins.csv\"))\n        .finish().unwrap()\n        .select([\n            col(\"species\"),\n            col(\"flipper_length_mm\").cast(DataType::Int16),\n            col(\"body_mass_g\").cast(DataType::Int16),\n        ])\n        .collect().unwrap();\n\n    ScatterPlot::builder()\n        .data(\u0026dataset)\n        .x(\"body_mass_g\")\n        .y(\"flipper_length_mm\")\n        .group(\"species\")\n        .opacity(0.5)\n        .size(12)\n        .colors(vec![\n            Rgb(178, 34, 34),\n            Rgb(65, 105, 225),\n            Rgb(255, 140, 0),\n        ])\n        .plot_title(\"Penguin Flipper Length vs Body Mass\")\n        .x_title(\"Body Mass (g)\")\n        .y_title(\"Flipper Length (mm)\")\n        .legend_title(\"Species\")\n        .build()\n        .plot();\n}\n```\n\nThis is the output:\n\n![Plot example](https://imgur.com/QMkmhNh.png)\n\nWith Plotlars, the same scatter plot is created with significantly less code.\nThe library abstracts away the complexities of dealing with individual plot\ncomponents and allows the user to specify high-level plot characteristics. This\nstreamlined approach not only saves time but also reduces the potential for\nerrors and makes the code more readable and maintainable.\n\n## Installation\n\n```bash\ncargo add plotlars\n```\n\n## Running the examples\n\nPlotlars comes with several ready‑to‑use demo programs in the `examples/` directory.\nYou can build and execute any of them with Cargo’s `--example` flag:\n\n```bash\ncargo run --example barplot\n```\n\nReplace `barplot` with the file name (without the `.rs` extension) of the example you want to run.\n\n## Features\n\n- Seamless Integration with Polars: Leverage the power of Polars for efficient\n  data manipulation and analysis.\n- Support for Multiple Plot Types: Easily create bar, line, scatter, and other\n  plot types.\n- Customization: Modify plot appearance with an intuitive API.\n\n## Plotlars in Jupyter Notebooks\n\nPlotlars seamlessly integrates with Jupyter Notebooks, allowing you to leverage\nthe power of interactive data visualization directly within your notebook\nenvironment. This integration is made possible through the use of the\n[evcxr project](https://github.com/evcxr/evcxr), which provides a Jupyter kernel\nfor the Rust programming language.\n\n![Jupyter notebook](https://imgur.com/zvFDzjj.png)\n\n**With Polars, evcxr, and Plotlars, data science in Rust leaps to the next level\n, making powerful data analysis and visualization more accessible and efficient\nthan ever before.**\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE.txt file for details.\n\n## Acknowledgements\n\n- [Polars](https://github.com/pola-rs/polars): For providing a fast and\n  efficient data manipulation library.\n- [Plotly](https://github.com/plotly/plotly.rs): For the inspiration and ideas\n  behind visualization libraries.\n- [Evcxr](https://github.com/evcxr/evcxr): For enabling the use of Rust in\n  Jupyter Notebooks.\n- Rust Community: For the support and development of an amazing programming\n  language.\n","funding_links":[],"categories":["Rust","Libraries/Packages/Scripts","\u003ca name=\"Rust\"\u003e\u003c/a\u003eRust"],"sub_categories":["Rust"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falceal%2Fplotlars","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falceal%2Fplotlars","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falceal%2Fplotlars/lists"}