{"id":13879103,"url":"https://github.com/red-data-tools/charty","last_synced_at":"2025-04-12T19:48:50.748Z","repository":{"id":47175430,"uuid":"118586991","full_name":"red-data-tools/charty","owner":"red-data-tools","description":"Visualizing your data in Ruby","archived":false,"fork":false,"pushed_at":"2025-04-08T08:20:36.000Z","size":4860,"stargazers_count":191,"open_issues_count":21,"forks_count":30,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-12T19:48:35.994Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/red-data-tools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-01-23T09:20:14.000Z","updated_at":"2025-04-08T08:20:40.000Z","dependencies_parsed_at":"2024-05-29T05:50:32.842Z","dependency_job_id":"4f951fb7-5995-4c1f-babd-1d6e081f4b8c","html_url":"https://github.com/red-data-tools/charty","commit_stats":{"total_commits":423,"total_committers":22,"mean_commits":"19.227272727272727","dds":"0.43262411347517726","last_synced_commit":"776a9ae1faa7a31111d9e4451e2db38f6ab96838"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red-data-tools%2Fcharty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red-data-tools%2Fcharty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red-data-tools%2Fcharty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/red-data-tools%2Fcharty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/red-data-tools","download_url":"https://codeload.github.com/red-data-tools/charty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625501,"owners_count":21135513,"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-06T08:02:09.935Z","updated_at":"2025-04-12T19:48:50.741Z","avatar_url":"https://github.com/red-data-tools.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Charty - Visualizing your data in Ruby\n\n![Build Status](https://github.com/red-data-tools/charty/workflows/CI/badge.svg)\n[![Gem Version](https://badge.fury.io/rb/charty.svg)](https://badge.fury.io/rb/charty)\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/red-data-tools/charty/master?filepath=iris_dataset.ipynb)\n[![Docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://rubydoc.info/gems/charty)\n\nCharty is open-source Ruby library for visualizing your data in a simple way.\nIn Charty, you need to write very few lines of code for representing what you want to do.\nIt lets you focus on your analysis of data, instead of plotting.\n\n![](https://github.com/red-data-tools/charty/raw/master/images/design_concept.png)\n\n## Installation\n\n### MacOS:\n\n```\n$ brew install Python\n$ pip3 install matplotlib\n$ bundle\n```\n\n### Ubuntu + pyenv\n\nYou should install tk libraries before install python and should add enabling shared library option to installing python.\nSo you may have to do `pyenv uninstall 3.x.x` first.\n\n```\n$ apt install -y tk-dev python3-tk\n$ CONFIGURE_OPTS=\"--enable-shared\" pyenv install 3.x.x\n```\n\n### With Matplotlib\n\n```\ngem install charty --pre\ngem install matplotlib\nsudo apt install python3-pip\nsudo python3 -m pip install -U pip matplotlib\n```\n\n## Development with Docker\n\ne.g.\n\n```\n$ docker build -f ./Dockerfile.dev -t charty-dev:latest .\n$ docker run --rm -v $(pwd):/charty charty-dev:latest bundle config set path vendor/bundle\n$ docker run --rm -v $(pwd):/charty charty-dev:latest bundle install\n$ docker run --rm -it -v $(pwd):/charty charty-dev:latest ./bin/console\nirb(main):001:0\u003e Charty::VERSION\n=\u003e \"0.2.2\"\n\n# When using jupyter notebook\n$ docker run --rm -it -v $(pwd):/charty -p 8888:8888 charty-dev:latest\n```\n\n## Usage\n\n### Statistical plotting interface\n\nCharty supports statistical plotting as Python's seaborn.\n\nIn the following examplles, we use the `penguins` dataset provided in red-datasets.\n\n```ruby\nrequire \"datasets\"\n\npenguins = Datasets::Penguins.new\n```\n\n#### A basic workflow\n\nThe following code shows a basic workflow of the visualization with Charty.\n\nFirst you need to load the Charty library.\n\n```ruby\nrequire \"charty\"\n```\n\nNext you msut have a dataset you want to visualize.  Here, we use the penguins dataset provided in red-datasets library.\n\n```ruby\nrequire \"datasets\"\npenguins = Datasets::Penguins.new\n```\n\nNext you need to create a plotter object by a plotting method.  Here, we use `scatter_plot` method to show the relationship\namong `body_mass_g`, `flipper_length_mm`, and `species` columns in the penguins dataset.\n\n```ruby\nplot = Charty.scatter_plot(data: penguins, x: :body_mass_g, y: :flipper_length_mm, color: :species)\n```\n\nIf you want to render and save this plotter object into an HTML file by plotly backend, you can do it like below.\n\n```ruby\nCharty::Backends.use(:plotly)  # select plotly backend\nplot.save(\"scatter.html\")      # save the plot as  an HTML file\n```\n\nWhen you already have prepared [playwright-ruby-client](https://github.com/YusukeIwaki/playwright-ruby-client),\nyou can render a plot into a PNG file by plotly backend by specifying a filename with `.png` extension.\n\n```ruby\nplot.save(\"scatter.png\")\n```\n\n#### Jupyter Notebook\n\nIf you use Charty on Jupyter Notebook with IRuby kerenl (a.k.a. IRuby notebook),\nyou can render the plot just evaluate a plotter object.  For example, the code below shows a scatter plot figure in\nthe output area.\n\n```ruby\nCharty::Backends.use(:plotly)\n\nCharty.scatter_plot(data: penguins, x: :body_mass_g, y: :flipper_length_mm, color: :species)\n```\n\nNote that if you want to use the pyplot backend, you need to activate the integration between the pyplot backend and IRuby.\nYou can activate the integration by the following two lines.\n\n```ruby\nCharty::Backends.use(:pyplot)\nCharty::Backends::Pyplot.activate_iruby_integration\n```\n\n#### Bar plot\n\nCharty's statistical bar plot shows the relationship between a categorical variable and estimated means of a numeric variable.\nThis plot automatically calculates mean estimation and its 95% confidence interval of the numeric variable.\n\nWhen we specify the categorical varaible as x-axis, the plot draws a vertical bar chart.\nInstead, when we specify the categorical variable as y-axis, the plot draws a horizontal bar chart.\n\nThe following code shows the relationship between species and the mean body masses of penguins in a vertical bar chart.\n\n```ruby\nCharty.bar_plot(data: penguins, x: :species, y: :body_mass_g)\n```\n\n![](images/penguins_species_body_mass_g_bar_plot_v.png)\n\nExchanging x and y axes alternates the orientation of the resulting chart.\n\n```ruby\nCharty.bar_plot(data: penguins, x: :body_mass_g, y: :species)\n```\n\n![](images/penguins_species_body_mass_g_bar_plot_h.png)\n\nAdding color axis introduces color grouping in the bar plot.\n\n```ruby\nCharty.bar_plot(data: penguins, x: :species, y: :body_mass_g, color: :sex)\n```\n\n![](images/penguins_species_body_mass_g_sex_bar_plot_v.png)\n\n#### Box plot\n\nCharty's statistical box plot shows distributions of a numeric variable per categories.\nThe distributions are showed by boxes with whiskers that characterized by five-number summary.\nThis plot automatically calculates five-number summary the numeric variable per categories.\n\nWhen we specify the categorical varaible as x-axis, the plot draws a vertical box plot chart.\nInstead, when we specify the categorical variable as y-axis, the plot draws a horizontal box plot chart.\n\nThe following code draws a vertical box plot to show distributions of penguins' body mass per species.\n\n```ruby\nCharty.box_plot(data: penguins, x: :species, y: :body_mass_g)\n```\n\n![](images/penguins_species_body_mass_g_box_plot_v.png)\n\nAs `bar_plot` above, exchanging x and y axes alternates the orientation of the resulting chart.\n\n```ruby\nCharty.box_plot(data: penguins, x: :body_mass_g, y: :species)\n```\n\n![](images/penguins_species_body_mass_g_box_plot_h.png)\n\nAdding color axis introduces color grouping in the box plot.\n\n```ruby\nCharty.box_plot(data: penguins, x: :species, y: :body_mass_g, color: :sex)\n```\n\n![](images/penguins_species_body_mass_g_sex_box_plot_v.png)\n\n#### Scatter plot\n\nCharty's scatter plot shows the relationship between two numeric variables.\n\n```ruby\nCharty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm)\n```\n\n![](images/penguins_body_mass_g_flipper_length_mm_scatter_plot.png)\n\nAdding color axis introduces color grouping in the scatter plot.\nThe following example specifies `:species` variable in the color axis.\nIt shows the different species by the different colors.\n\n```ruby\nCharty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm, color: :species)\n```\n\n![](images/penguins_body_mass_g_flipper_length_mm_species_scatter_plot.png)\n\nMoreover, size and style axes can be specified.\nThe following example specifies `:sex` variable in the style axis.\n\n```ruby\nCharty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm, color: :species, style: :sex)\n```\n\n![](images/penguins_body_mass_g_flipper_length_mm_species_sex_scatter_plot.png)\n\n### Old-style plotting interface\n\n```ruby\nrequire 'charty'\ncharty = Charty::Plotter.new(:pyplot)\n\nbar = charty.bar do\n  series [0,1,2,3,4], [10,40,20,90,70], label: \"sample1\"\n  series [0,1,2,3,4], [90,80,70,60,50], label: \"sample2\"\n  series [0,1,2,3,4,5,6,7,8], [50,60,20,30,10, 90, 0, 100, 50], label: \"sample3\"\n  range x: 0..10, y: 1..100\n  xlabel 'foo'\n  ylabel 'bar'\n  title 'bar plot'\nend\nbar.render(\"sample_images/bar_pyplot.png\")\n```\n\nCharty also supports Daru::DataFrame, Numo::NArray and ActiveRecord as Data Abstraction Layer.\nFor example.\n\n```ruby\nrequire 'charty'\ncharty = Charty::Plotter.new(:pyplot)\n\n\n### when Daru::DataFrame\nrequire 'daru'\ndf = Daru::DataFrame.new({'a':[1,2,3,4], 'b':[4,5,6,7], 'c':[8, 9, 10, 11]})\ncharty.table = df\n\n\n### when Numo::NArray\nrequire \"numo/narray\"\nnarray = Numo::DFloat.new(3,5).seq\ncharty.table = narray\n\n\n### when ActiveRecord\nrequire \"active_record\"\nActiveRecord::Base.establish_connection(adapter: \"sqlite3\", database: \":memory:\")\nActiveRecord::Schema.define do\n  create_table :foos do |t|\n    t.integer :price\n    t.integer :sales\n  end\nend\nclass Foo \u003c ActiveRecord::Base\nend\n100.times{|i| Foo.create!(price: 10 * i, sales: (1..100).to_a.sample) }\nsales = Foo.where(\"sales \u003e= 40\")\ncharty.table = sales\n\n\nbar = charty.to_bar(:price, :sales)\nbar.render('sample')\n\nbox_plot = charty.to_box_plot(:price, :sales)\nbox_plot.render('sample')\n\nbubble = charty.to_bubble(:price, :sales, :id)\nbubble.render('sample')\n\ncurve = charty.to_curve(:price, :sales)\ncurve.render('sample')\n\nscatter = charty.to_scatter(:price, :sales)\nscatter.render('sample')\n\nerror_bar = charty.to_error_bar(:price, :sales)\nerror_bar.render('sample')\n\nhst= charty.to_hst(:price, :sales)\nhst.render('sample')\n```\n\n## Examples\n\ncreate an instance of the library you want to use.\n\n```ruby\nrequire 'charty'\n\n# when you want to use matplotlib.pyplot\ncharty = Charty::Plotter.new(:pyplot)\n\n# when you want to use gruff\ncharty = Charty::Plotter.new(:gruff)\n\n# when you wanto to use rubyplot\ncharty = Charty::Plotter.new(:rubyplot)\n```\n\n### Bar\n\n```ruby\nbar = charty.bar do\n  series [0,1,2,3,4], [10,40,20,90,70], label: \"sample1\"\n  series [0,1,2,3,4], [90,80,70,60,50], label: \"sample2\"\n  series [0,1,2,3,4,5,6,7,8], [50,60,20,30,10, 90, 0, 100, 50], label: \"sample3\"\n  range x: 0..10, y: 1..100\n  xlabel 'foo'\n  ylabel 'bar'\n  title 'bar plot'\nend\nbar.render(\"sample_images/bar_pyplot.png\")\n```\n\n#### PyPlot\n\n![bar pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/bar_pyplot.png)\n\n#### Gruff\n\n![bar gruff](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/bar_gruff.png)\n\n#### Rubyplot\n\n![bar rubyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/bar_rubyplot.png)\n\n### Curve\n\n```ruby\ncurve2 = charty.curve do\n  series [0,1,2,3,4], [10,40,20,90,70], label: \"sample1\"\n  series [0,1,2,3,4], [90,80,70,60,50], label: \"sample2\"\n  series [0,1,2,3,4,5,6,7,8], [50,60,20,30,10, 90, 0, 100, 50], label: \"sample3\"\n  range x: 0..10, y: 1..100\n  xlabel 'foo'\n  ylabel 'bar'\nend\ncurve2.render(\"sample_images/curve_pyplot.png\")\n```\n\n#### PyPlot\n\n![curve2 pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/curve_pyplot.png)\n\n#### Gruff\n\n![curve2 gruff](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/curve_gruff.png)\n\n#### Rubyplot\n\n![curve2 rubyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/curve_rubyplot.png)\n\n### Curve with function\n\n```ruby\ncurve = charty.curve do\n  function {|x| Math.sin(x) }\n  range x: 0..10, y: -1..1\n  xlabel 'foo'\n  ylabel 'bar'\nend\ncurve.render(\"sample_images/curve_with_function_pyplot.png\")\n```\n\n#### PyPlot\n\n![curve pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/curve_with_function_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\n![curve rubyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/curve_with_function_rubyplot.png)\n\n### Box plot\n\n```ruby\nbox_plot = charty.box_plot do\n  data [[60,70,80,70,50], [100,40,20,80,70], [30, 10]]\n  range x: 0..10, y: 1..100\n  xlabel 'foo'\n  ylabel 'bar'\n  title 'box plot'\nend\nbox_plot.render(\"sample_images/box_plot_pyplot.png\")\n```\n\n#### PyPlot\n\n![box pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/box_plot_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\nNot supported\n\n### Scatter\n\n```ruby\nscatter = charty.scatter do\n  series 0..10, (0..1).step(0.1), label: 'sample1'\n  series 0..5, (0..1).step(0.2), label: 'sample2'\n  series [0, 1, 2, 3, 4], [0, -0.1, -0.5, -0.5, 0.1], label: 'sample3'\n  range x: 0..10, y: -1..1\n  # xlabel 'x label'\n  # xlabel ''\n  ylabel 'y label'\n  title 'scatter sample'\nend\nscatter.render(\"sample_images/scatter_pyplot.png\")\n```\n\n#### PyPlot\n\n![scatter pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/scatter_pyplot.png)\n\n#### Gruff\n\n![scatter gruff](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/scatter_gruff.png)\n\n#### Rubyplot\n\n![scatter rubyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/scatter_rubyplot.png)\n\n### Errorbar\n\n```ruby\nerror_bar = charty.error_bar do\n  series [1,2,3,4], [1,4,9,16], xerr: [0.5,1.0,1.5,0.3], yerr: [0.6,0.2,0.8,0.1], label: 'label1'\n  series [1,2,3,4], [16,9,4,1], label: 'label2'\n  series [1,2,3,4,5,6,7,8], [14,14,14,14,14,14,14,14], label: 'label2', xerr: [0.5,1.0,1.5,0.3, 1.1, 1.2, 1.3, 1.4]\n  range x: 0..10, y: -1..20\n  xlabel 'x label'\n  title 'error_bar'\nend\nerror_bar.render(\"sample_images/error_bar_pyplot.png\")\n```\n\n#### PyPlot\n\n![error_bar pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/error_bar_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\nNot supported\n\n### Bubble chart\n\n```ruby\nbubble = charty.bubble do\n  series 0..10, (0..1).step(0.1), [10, 100, 1000, 20, 200, 2000, 5, 50, 500, 4, 40], label: 'sample1'\n  series 0..5, (0..1).step(0.2), [1, 10, 100, 1000, 500, 100], label: 'sample2'\n  series [0, 1, 2, 3, 4], [0, -0.1, -0.5, -0.5, 0.1], [40, 30, 200, 10, 5]\n  range x: 0..10, y: -1..1\n  xlabel 'x label'\n  ylabel 'y label'\n  title 'bubble sample'\nend\nbubble.render(\"sample_images/bubble_pyplot.png\")\n```\n\n#### PyPlot\n\n![bubble pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/bubble_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\n![bubble rubyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/bubble_rubyplot.png)\n\n### Histogram\n\n```ruby\nhist = charty.hist do\n  data [[10, 10, 20, 30, 40, 40,40,40,40,40, 50, 10, 10, 10], [100, 100, 100, 100, 90, 90, 80, 30, 30, 30, 30, 30]]\n  range x: 0..100, y: 0..7\n  xlabel 'x label'\n  ylabel 'y label'\n  title 'histogram sample'\nend\nhist.render(\"sample_images/hist_pyplot.png\")\n```\n\n#### PyPlot\n\n![hist pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/hist_pyplot.png)\n\n#### Gruff\n\n![hist_gruff](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/hist_gruff.png)\n\n#### Rubyplot\n\nNot supported\n\n### Subplots\n\n```ruby\nlayout = charty.layout\nlayout \u003c\u003c curve\nlayout \u003c\u003c scatter\nlayout.render(\"sample_images/subplot_pyplot.png\")\n```\n\n#### PyPlot\n\n![subplot pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/subplot_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\nNot supported\n\n### Subplots 2\n\n```ruby\ncurve_list = [0.5, 0.75].map do |f|\n  charty.curve(f:f) do\n    function {|x| Math.sin(f*x) }\n    range x: 0..10, y: -1..1\n  end\nend\n\nscatter_list = [-0.5, 0.5].map do |f|\n   charty.scatter(f: f) do\n    series Charty::Linspace.new(0..10, 20), Charty::Linspace.new(0..f, 20)\n    range x: 0..10, y: -1..1\n  end\nend\n\ngrid_layout = charty.layout(:grid2x2)\ngrid_layout \u003c\u003c curve_list\ngrid_layout \u003c\u003c scatter_list\ngrid_layout.render(\"sample_images/subplot2_pyplot.png\")\n```\n\n#### PyPlot\n\n![subplot2 pyplot](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/subplot2_pyplot.png)\n\n#### Gruff\n\nNot supported\n\n#### Rubyplot\n\nNot supported\n\n\n## Acknowledgements\n\n- The concepts of this library is borrowed from Python's [HoloViews](http://holoviews.org/) and Julia's [Plots ecosystem](https://juliaplots.github.io/).\n\n## Authors\n\n- Kenta Murata \\\u003cmrkn@mrkn.jp\\\u003e\n- Kazuma Furuhashi \\\u003ck.furuhashi10@gmail.com\\\u003e\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fred-data-tools%2Fcharty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fred-data-tools%2Fcharty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fred-data-tools%2Fcharty/lists"}