DEV Community

kojix2
kojix2

Posted on • Edited on

3 1

Introduction to GR.rb - data visualization with Ruby

GitHub logo kojix2 / GR.rb

Ruby wrapper for the GR framework

GR.rb

Gem Version CI Gitter Chat Docs Latest

rdatasets-1 stem histogram barplot scatter3 volume griddata 2darray 2dpolararray hexbin rdatasets-2 rdatasets-3 surface face shade

📊 GR framework - powerful visualization library - for Ruby

Installation

First, install GR. Then install gr-plot gem.

gem install gr-plot
Enter fullscreen mode Exit fullscreen mode

pkg-config will detect the location of the shared library. Otherwise, you need to specify the environment variable.

export GRDIR="/your/path/to/gr"
Enter fullscreen mode Exit fullscreen mode

Quick Start

👉 Wiki -plotting functions

require 'gr/plot'

x = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
y = [0.3, 0.5, 0.4, 0.2, 0.6, 0.7]

# show the figure
GR.plot(x, y)

# Save the figure in PNG format.
GR.savefig("figure.png")
Enter fullscreen mode Exit fullscreen mode

GR.rb supports Jupyter Notebook / Lab.

API Overview

GR::Plot - A simple, matlab-style API

require 'gr/plot'
GR.plot(x, y)
Enter fullscreen mode Exit fullscreen mode

List of available functions.

plot step plot3 polar scatter scatter3 stem barplot histogram polarhistogram hexbin contour contourf

GR.rb is a Ruby visualization tool I've been working since last fall. This is the binding of GR Framework, which is the default backend for Plots.jl. Here you can see a gallery of some of our examples.

Getting ready

Install GR Framework.
Set environment variable GRDIR.

export GRDIR="/your/path/to/gr"
gem install ruby-gr
```



you'll need the `ruby-gr`, `numo-narray` gems.



```
gem install ruby-gr
```





```ruby
require 'gr/plot'
require 'numo/narray'
```



## Line Plots



```ruby
x = Numo::DFloat.linspace(0, 10, 1001)
y = Numo::NMath.sin(x)

GR.plot(x, y)
```



![](https://user-images.githubusercontent.com/5798442/80851620-c1d48900-8c5d-11ea-8c78-376bb3b2d644.png)



```ruby
x = Numo::DFloat.linspace(0, 10, 51)
y = Numo::NMath.sin(x)

GR.step(x, y)
```



![](https://user-images.githubusercontent.com/5798442/80851791-c188bd80-8c5e-11ea-865f-527db1846a61.png)



```ruby
x = Numo::DFloat.linspace(0, 30, 1000)
y = Numo::NMath.cos(x) * x
z = Numo::NMath.sin(x) * x

GR.plot3(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80851853-188e9280-8c5f-11ea-9416-44a558706607.png)



```ruby
angles = Numo::DFloat.linspace(0, 2 * Math::PI, 40)
radii = Numo::DFloat.linspace(0, 20, 40)

GR.polar(angles, radii)
```



![](https://user-images.githubusercontent.com/5798442/80851874-47a50400-8c5f-11ea-89ff-1186d5942801.png)

## Scatter Plots



```ruby
x = Numo::DFloat.linspace(0, 1, 51)
y = x - x**2
s = x * 200

GR.scatter(x, y, s)
```



![](https://user-images.githubusercontent.com/5798442/80852173-73c18480-8c61-11ea-9625-cdaf4c07a659.png)



```ruby
x = Numo::DFloat.linspace(0, 1, 51)
y = x - x**2
s = Numo::DFloat.linspace(50, 300, x.size)
c = Numo::DFloat.linspace(0, 255, x.size)

GR.scatter(x, y, s, c)
```



![](https://user-images.githubusercontent.com/5798442/80852185-850a9100-8c61-11ea-8e41-3a49cae38b9d.png)



```ruby
x = 2 * Numo::DFloat.new(100).rand - 1
y = 2 * Numo::DFloat.new(100).rand - 1
z = 2 * Numo::DFloat.new(100).rand - 1
c = 999 * Numo::DFloat.new(100).rand + 1

GR.scatter3(x, y, z, c)
```



![](https://user-images.githubusercontent.com/5798442/80852233-e3d00a80-8c61-11ea-805a-2b1356425dba.png)

## Stem Plots



```ruby
x = Numo::DFloat.linspace(-2, 2, 40)
y = x ** 3 + x ** 2 + x + 6

GR.stem(x, y)
```



![](https://user-images.githubusercontent.com/5798442/80852331-b0da4680-8c62-11ea-99ee-e393acf86028.png)

## Bar Plots



```ruby
continents = ["Africa", "America", "Asia", "Europe", "Oceania"]
population_2010 = [1044, 944, 4170, 735, 36]

GR.barplot(continents, population_2010)
```



![](https://user-images.githubusercontent.com/5798442/80907904-b49ac580-8d55-11ea-87f4-59dc14196c26.png)

## Histograms



```ruby
x = Numo::DFloat.new(10_000).rand_norm

GR.histogram(x)
```



![image](https://user-images.githubusercontent.com/5798442/80852386-1f1f0900-8c63-11ea-91e6-a01d9c2530cb.png)



```ruby
x = Numo::DFloat.new(10_000).rand_norm
y = Numo::DFloat.new(10_000).rand_norm

GR.hexbin(x, y)
```



![image](https://user-images.githubusercontent.com/5798442/80852515-2a266900-8c64-11ea-8eec-84fa20379174.png)

## Contour Plots



```ruby
x = 8 * Numo::DFloat.new(60).rand - 4
y = 8 * Numo::DFloat.new(60).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.contour(x, y, z)
```



![image](https://user-images.githubusercontent.com/5798442/80852802-635fd880-8c66-11ea-90e8-bd8f6489d3ca.png)



```ruby
_x = Numo::DFloat.linspace(-2, 2, 40)
_y = Numo::DFloat.linspace(0, Math::PI, 20)
x = (_x.expand_dims(0) * Numo::DFloat.ones(_y.size, 1)).flatten
y = (_y.expand_dims(1) * Numo::DFloat.ones(1, _x.size)).flatten
z = (Numo::NMath.sin(x) + Numo::NMath.cos(y)).flatten

GR.contour(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80852673-50003d80-8c65-11ea-95bf-ddd3d363692a.png)



```ruby
x = 8 * Numo::DFloat.new(100).rand - 4
y = 8 * Numo::DFloat.new(100).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.contourf(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80852853-eb45e280-8c66-11ea-857b-4abfd5675374.png)



```ruby
x = 8 * Numo::DFloat.new(300).rand - 4
y = 8 * Numo::DFloat.new(300).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.tricont(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80852926-96569c00-8c67-11ea-889d-852b585ceafc.png)

## Surface Plots



```ruby
x = 8 * Numo::DFloat.new(100).rand - 4
y = 8 * Numo::DFloat.new(100).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.surface(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80854132-9dce7300-8c70-11ea-9ae6-3d4a7a0d2f88.png)



```ruby
x = 8 * Numo::DFloat.new(100).rand - 4
y = 8 * Numo::DFloat.new(100).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.trisurf(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80854210-264d1380-8c71-11ea-9d9e-7e8182f06c1b.png)



```ruby
x = 8 * Numo::DFloat.new(1000).rand - 4
y = 8 * Numo::DFloat.new(1000).rand - 4
z = Numo::NMath.sin(x) + Numo::NMath.cos(y)

GR.wireframe(x, y, z)
```



![](https://user-images.githubusercontent.com/5798442/80854250-75934400-8c71-11ea-9278-352c74d97b82.png)

## Volume Rendering



```ruby
z = Numo::DFloat.new(50, 50, 50).rand_norm

GR.volume(z)
```



![](https://user-images.githubusercontent.com/5798442/80854306-ffdba800-8c71-11ea-984e-192533d0a2ea.png)

## Heatmaps



```ruby
x = Numo::DFloat.linspace(-2, 2, 40)
y = Numo::DFloat.linspace(0, Math::PI, 20)
z = Numo::NMath.sin(x).expand_dims(0).transpose + Numo::NMath.cos(y)

GR.heatmap(z)
```



![image](https://user-images.githubusercontent.com/5798442/80854477-a5434b80-8c73-11ea-8a77-8f6f23085781.png)



```ruby
n = 1_000_000
x = Numo::DFloat.new(n).rand_norm
y = Numo::DFloat.new(n).rand_norm

GR.shade(x, y)
```



![](https://user-images.githubusercontent.com/5798442/80854645-c48ea880-8c74-11ea-8364-7351e11b60c7.png)

## Images



```ruby
x = Numo::DFloat.linspace(-1, 1, 20)
y = Numo::DFloat.linspace(0, Math::PI, 30)
z = Numo::NMath.sin(x).expand_dims(0).transpose + Numo::NMath.cos(y)

GR.imshow(z)
```



![](https://user-images.githubusercontent.com/5798442/80857969-2bba5600-8c91-11ea-850c-e682ebf1f843.png)

## Isosurfaces



```ruby
s = Numo::DFloat.linspace(-0.6, 0.6, 50)
v = 1 - ((s**2 +  (s**2).expand_dims(0).transpose).expand_dims(2) + s.reshape(1, 1, true)**2)**0.5

GR.isosurface(v)
```



![](https://user-images.githubusercontent.com/5798442/80867161-94bfbf00-8ccd-11ea-9405-9293634ae030.png)

## Subplots



```ruby
require 'gr/plot'

x = [1,2,3,4,5,6,7,8,9,10]
y = x.shuffle

GR.barplot x, y, GR.subplot(2, 2, 1)
GR.stem    x, y, GR.subplot(2, 2, 2)
GR.step    x, y, GR.subplot(2, 2, 3)
GR.plot    x, y, GR.subplot(2, 2, 4)
```



![](https://user-images.githubusercontent.com/5798442/80975253-cfa42d00-8e5c-11ea-8f75-4644a861002a.png)

## Resources
* https://github.com/red-data-tools/GR.rb/wiki/
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay