• Stars
    star
    48
  • Rank 594,835 (Top 12 %)
  • Language
    Crystal
  • License
    Other
  • Created almost 7 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Graph plotting package with a small API and sensible defaults powered by gnuplot.

石の上にも三年

GitHub Release Build Status Documentation

Graph plotting package with a small API and sensible defaults powered by gnuplot.

Requires gnuplot.

Installation

  1. Add the dependency to your shard.yml:
dependencies:
  ishi:
    github: toddsundsted/ishi
  1. Run shards install

Usage

To display a line chart of the data points in xdata (the x values) and ydata (the corresponding y values):

require "ishi"

ishi = Ishi.new
ishi.plot(xdata, ydata)
ishi.show

Or, if you prefer command-style syntax:

require "ishi"

Ishi.new do
  plot(xdata, ydata)
end

A chart can display multiple plots. The following code displays two plots in one chart: one derived from discrete data points and the other from the equation of a line.

require "ishi"

Ishi.new do
  plot([1, 2, 3, 4, 5], [1.0, 1.4, 1.9, 2.4, 2.6], "ko", title: "data")
  plot("0.4 * x + 0.7", "b--")
end

two plots

The etc/examples directory contains examples of usage.

plot

plot plots points and lines. It takes data in several formats:

  • plot(ydata) - y values in ydata with x values ranging from 0 to ydata.size - 1
  • plot(xdata, ydata) - x values in xdata and corresponding y values in ydata
  • plot(xdata, ydata, zdata) - x values in xdata, y values in ydata, and z values in zdata
  • plot(expression) - any gnuplot-supported mathematical expression

xdata, ydata and zdata may be any type that implements Indexable(Number). Chart dimensionality (2D or 3D) is inferred from the data.

All plot methods/commands accept the optional named arguments title, style, dashtype (dt), linecolor (lc), linewidth (lw), pointsize (ps), pointtype (pt), linestyle (ls), fillstyle (fs) and format.

title specifies the title of the plot in the chart key.

style explicitly specifies the style of the plot (:lines, :points, etc.). Ishi will try to infer the style from the data and the other named arguments (for example, if both linewidth and pointsize are provided, the style will be :linespoints).

By default, plots are rendered with solid lines. dashtype (dt) specifies the pattern of dashes to use instead. dashtype may be an array of pairs of numbers that specify the length of a solid line followed by the length of an empty space (e.g. [2, 3, 5, 7]), or it may be a string composed of . (dot), - (hyphen), _ (underscore) and (space), which is then converted into an array as follows: each "." becomes [2, 5], "-" becomes [10, 10], "_" becomes [20, 10] and " " adds 10 to the previous empty value.

linecolor specifies the color to use for lines and points. Colors may be specified by name (e.g. "red", "blue", or "green") or by hexadecimal color value (e.g. "#AARRGGBB" or "#RRGGBB").

linewidth and pointsize scale the width of lines and the size of points, respectively. A value of 2.0 is twice as big as the default width or size.

The following code demonstrates the use of dashtype, linecolor and linewidth:

require "ishi"

Ishi.new do
  plot("x + 4.0", dashtype: "-", linewidth: 2)
  plot("x + 3.0", dashtype: "_", linewidth: 2)
  plot("x + 2.0", dashtype: ".", linewidth: 2)
  plot("x + 1.0", dashtype: "..._", linewidth: 2)
  plot("x + 0.0", dashtype: [30, 10, 50, 10], linewidth: 2, linecolor: "#88001100")
end

lines

pointtype selects the type of point to render. Available types depend on the gnuplot terminal device used, but commonly supported values are . (dot), + (plus sign), x (multiplication sign), * (asterisk), s (square), o (circle), ^ (up triangle), and v (down triangle) and d (diamond).

The following code demonstrates the use of pointtype and pointsize:

require "ishi"

Ishi.new do
  plot([1, 2, 3, 4], [5, 6, 7, 8], pointtype: 1, pointsize: 2)
  plot([1, 2, 3, 4], [4, 5, 6, 7], pointtype: "o", pointsize: 2)
  plot([1, 2, 3, 4], [3, 4, 5, 6], pointtype: "s", pointsize: 2)
  plot([1, 2, 3, 4], [2, 3, 4, 5], pointtype: "^", pointsize: 2)
  plot([1, 2, 3, 4], [1, 2, 3, 4], pointtype: "v", pointsize: 2, linecolor: "#88001100")
end

points

The format argument is a short string used to specify color, point and line, simultaneously.

Color is a letter from the set b (blue), g (green), r (red), c (cyan), m (magenta), y (yellow), k (black) or w (white). Point is a letter from the set . (dot), + (plus sign), x (multiplication sign), * (asterisk), s (square), c (circle), ^ (up triangle), v (down triangle) or d (diamond). Line may be - (solid line), -- (dashed line), ! (dash-dot line) and : (dotted line).

Given these rules, the format string "b" is a solid blue line, "or" is red circles, "^k:" is black triangles connected by dotted black lines, "g-" is a solid green line and "--" is a dashed line.

format may also be a single word color name or hexadecimal color value, in which case point and line may not be specified.

Returning to the first example, the code uses format to customize the plots:

require "ishi"

Ishi.new do
  plot([1, 2, 3, 4, 5], [1.0, 1.4, 1.9, 2.4, 2.6], "ko", title: "data")
  plot("0.4 * x + 0.7", "b--")
end

The format "ko" could also be expressed explicitly (and much more verbosely) with the named arguments linecolor: "black", pointtype: 7, and the format "b--" with linecolor: "blue", dashtype: 2.

scatter

scatter draws scatter plots. It takes data in several formats:

  • scatter(xdata, ydata) - x values in xdata and corresponding y values in ydata
  • scatter(xdata, ydata, zdata) - x values in xdata, y values in ydata, and z values in zdata

Chart dimensionality (2D or 3D) is inferred from the data. By default, scatter places a . (dot) at each point.

All scatter methods/commands accept the optional named arguments title, style, dashtype (dt), linecolor (lc), linewidth (lw), pointsize (ps), pointtype (pt), linestyle (ls) and format.

The following code demonstrates the use of scatter:

require "ishi"

Ishi.new do
  scatter(xdata, zdata, lc: "#4b03a1")
  scatter(ydata, zdata, lc: "#b5367a")
end

scatter

imshow

imshow displays data as a pseudocolor, heatmapped image:

  • imshow(data) - data is two-dimensional scalar data, which will be rendered as an image

The following code demonstrates the use of imshow:

require "ishi"

Ishi.new do
  palette(:inferno)
  imshow(data)
  margin(0, 0, 0, 0)
  show_colorbox(false)
  show_border(false)
  show_xtics(false)
  show_ytics(false)
  show_key(false)
end

imshow

charts

charts changes the number of charts in the figure:

  • charts(rows, cols) - rows and cols are the number of rows and columns in the figure

By default a figure has one chart. This call changes the number of charts in the figure. The original chart is preserved and becomes the chart in the first row, first column of the new layout.

When called without a block, charts returns the charts in the figure.

require "ishi"

figure = Ishi.new
charts = figure.charts(2, 2)
charts[0].plot([1, 2, 3, 4])
charts[1].plot([1, 1, 3, 2])
charts[2].plot([1, 1, 1, 1])
charts[3].plot([4, 3, 2, 1])
figure.show

When called with a block, charts Yields each chart as the default receiver of the supplied block. Block arguments are i (the i-th chart in the figure), row and col (the row and column of the chart).

require "ishi"

figure = Ishi.new
figure.charts(2, 2) do |i, row, col|
  plot([1, 2, 3, 4].rotate(i), title: "#{row},#{col}")
end
figure.show

Non-numeric labels on the x-axis

xtics sets non-numeric labels for positions on the x-axis.

The following code demonstrates the use of xtics:

require "ishi"

Ishi.new do
  x = [1, 2, 3]
  y = [65, 30, 5]
  plot(x, y, title: "Visits", style: :boxes, fs: 0.25)
    .boxwidth(0.5)
    .ylabel("Visits (%)")
    .xlabel("Device")
    .xtics({
      1.0 => "mobile",
      2.0 => "desktop",
      3.0 => "tablet"
    })
end

xtics

MXNet::NDArray

MXNet::NDArray is an indexable, multi-dimensional array that efficiently supports numerical operations (transposition, matrix multiplication, etc.).

All appropriate methods/commands accept instances of MXNet::NDArray with the correct shape (1-dimensional vectors for x-values, for example).

require "ishi"
require "mxnet"

m = MXNet::NDArray.array(
  [[0, 0, 1, 1],
   [1, 2, 3, 4],
   [1, 1, 2, 2]]
)

figure = Ishi.new
charts = figure.charts(1, 2)
charts[0].plot(m[0], m[1], m[2])
charts[1].plot(m[.., 0], m[.., 1], m[.., 2])
figure.show

See MXNet.cr for more information on the complete library.

Extensions

By default, Ishi pops open a window to display charts. However, Ishi comes with extensions that render charts as text, HTML, PNG or inline images in the terminal; or that write to other IO destinations. Note: terminal image display only works with ITerm2.

To plot the sin(x) function as text:

require "ishi/text" # or "ishi/html" or "ishi/iterm2"

Ishi.new do
  plot("sin(x)")
end

This produces:

    1 +--------------------------------------------------------------------+
      |                *  *              +  *  **         +       *  *     |
  0.8 |-+             *   *                 *    *          sin(x* *******-|
      |              *     *                *    *               *    *    |
  0.6 |-+            *      *              *     *               *     * +-|
      |              *      *             *       *             *       *  |
  0.4 |*+            *      *             *       *             *       *+-|
      |*            *        *            *        *           *        *  |
  0.2 |*+           *        *            *        *           *        *+-|
      | *          *          *          *         *          *          * |
    0 |-*          *          *          *         *          *          *-|
      |  *         *          *         *           *         *           *|
 -0.2 |-+*         *          *         *           *         *          +*|
      |  *        *            *       *             *       *            *|
 -0.4 |-+*        *            *       *             *       *           +*|
      |   *      *              *      *             *      *              |
 -0.6 |-+ *     *               *     *              *      *            +-|
      |    *    *               *     *               *     *              |
 -0.8 |-+   *   *                *   *                 *   *             +-|
      |     *  *       +         **  *   +             *  *                |
   -1 +--------------------------------------------------------------------+
     -10              -5                 0                5                10

You can pass in an IO instance. Chart data will be written to the IO instance instead of STDOUT.

require "ishi/text" # or "ishi/html" or "ishi/png"

io = IO::Memory.new

Ishi.new(io) do
  plot("sin(x)")
end

Contributors

More Repositories

1

ktistec

Single user ActivityPub (https://www.w3.org/TR/activitypub/) server.
Crystal
358
star
2

stunt

LambdaMOO with multiple inheritance, anonymous objects, HTTP, JSON <-> MOO translation, better crypto, a map datatype and a RESTful interface.
C++
72
star
3

mxnet.cr

MXNet (AI/ML) bindings for the Crystal language.
Crystal
22
star
4

improvise

Starter kit for Stunt.
JavaScript
18
star
5

Public-Suffix-List

Ruby code for working with the Public Suffix List
Ruby
12
star
6

rmoo

A major mode for interacting with MOOs.
Emacs Lisp
12
star
7

deep-learning

Exercises in deep learning -- Crystal language edition
Crystal
10
star
8

web_finger

A WebFinger (https://tools.ietf.org/html/rfc7033) client for Crystal.
Crystal
9
star
9

jquery.tweetcapture

Capture Twitter search tweets in real time and stick them in a web-page.
JavaScript
7
star
10

iterm2

Display images within the terminal using the ITerm2 Inline Images Protocol.
Crystal
6
star
11

slang

Slim-inspired templating language for Crystal
Crystal
5
star
12

host_meta

A Web Host Metadata (https://tools.ietf.org/html/rfc6415) client for Crystal.
Crystal
3
star
13

shiken

Basic Rails and Git skills test for candidates.
Ruby
3
star
14

javascript-as3-socket

Git clone of http://code.google.com/p/javascript-as3-socket/ with improvements.
JavaScript
3
star
15

heroku-buildpack-stunt

Heroku buildpack for Stunt.
Shell
2
star
16

openssl_ext

Crystal bindings for OpenSSL RSA
Crystal
2
star
17

ki

A simple mobile agent framework, described in a series of articles for JavaWorld c. 1998.
Java
2
star
18

pwnserver

It's my data and I wants it back!
2
star
19

public_suffix

A small Crystal library designed to make the Public Suffix List (https://publicsuffix.org/) easier to use.
Crystal
2
star
20

compare-cores

Compares two LambdaMOO databases (with extensions).
Perl
2
star
21

moocode-mode

A fork of Rob Myers' Emacs major mode providing syntax highlighting and indentation for MOO code.
Emacs Lisp
2
star
22

rubyweb

Rubyweb - a literate programming system for Ruby
Ruby
1
star
23

zzz

Hypermedia controls.
1
star
24

Scala-for-Scripting

Scala
1
star
25

libxml_ext

Extensions to XML in Crystal.
Crystal
1
star
26

iui

Custom version of the IUI iPhone webapp library.
JavaScript
1
star