{"id":13807574,"url":"https://github.com/toddsundsted/ishi","last_synced_at":"2025-03-21T20:32:42.265Z","repository":{"id":48814455,"uuid":"113598034","full_name":"toddsundsted/ishi","owner":"toddsundsted","description":"Graph plotting package with a small API and sensible defaults powered by gnuplot.","archived":false,"fork":false,"pushed_at":"2021-07-10T12:54:53.000Z","size":1076,"stargazers_count":48,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-12T19:41:24.362Z","etag":null,"topics":["chart","crystal","gnuplot"],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/toddsundsted.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}},"created_at":"2017-12-08T17:03:52.000Z","updated_at":"2024-05-11T09:45:25.000Z","dependencies_parsed_at":"2022-09-15T05:53:05.006Z","dependency_job_id":null,"html_url":"https://github.com/toddsundsted/ishi","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddsundsted%2Fishi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddsundsted%2Fishi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddsundsted%2Fishi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddsundsted%2Fishi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toddsundsted","download_url":"https://codeload.github.com/toddsundsted/ishi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221818447,"owners_count":16885754,"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":["chart","crystal","gnuplot"],"created_at":"2024-08-04T01:01:27.071Z","updated_at":"2024-10-28T10:46:24.520Z","avatar_url":"https://github.com/toddsundsted.png","language":"Crystal","funding_links":[],"categories":["Science and Data analysis"],"sub_categories":[],"readme":"# 石の上にも三年\n\n[![GitHub Release](https://img.shields.io/github/release/toddsundsted/ishi.svg)](https://github.com/toddsundsted/ishi/releases)\n[![Build Status](https://github.com/toddsundsted/ishi/actions/workflows/ci.yml/badge.svg)](https://github.com/toddsundsted/ishi/actions)\n[![Documentation](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://toddsundsted.github.io/ishi/)\n\nGraph plotting package with a small API and sensible defaults powered by gnuplot.\n\nRequires [gnuplot](http://www.gnuplot.info/).\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n```yaml\ndependencies:\n  ishi:\n    github: toddsundsted/ishi\n```\n\n2. Run `shards install`\n\n## Usage\n\nTo display a line chart of the data points in `xdata` (the x values)\nand `ydata` (the corresponding y values):\n\n```crystal\nrequire \"ishi\"\n\nishi = Ishi.new\nishi.plot(xdata, ydata)\nishi.show\n```\n\nOr, if you prefer command-style syntax:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  plot(xdata, ydata)\nend\n```\n\nA chart can display multiple plots. The following code displays two\nplots in one chart: one derived from discrete data points and the\nother from the equation of a line.\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  plot([1, 2, 3, 4, 5], [1.0, 1.4, 1.9, 2.4, 2.6], \"ko\", title: \"data\")\n  plot(\"0.4 * x + 0.7\", \"b--\")\nend\n```\n\n![two plots](https://raw.githubusercontent.com/toddsundsted/ishi/e277adfe71bf8ad3ead70fab9b3736ed969608d7/etc/examples/1.png)\n\nThe [etc/examples](https://github.com/toddsundsted/ishi/tree/main/etc/examples) directory contains examples of usage.\n\n### plot\n\n`plot` plots points and lines. It takes data in several formats:\n* `plot(ydata)` - y values in *ydata* with x values ranging from `0` to `ydata.size - 1`\n* `plot(xdata, ydata)` - x values in *xdata* and corresponding y values in *ydata*\n* `plot(xdata, ydata, zdata)` - x values in *xdata*, y values in *ydata*, and z values in *zdata*\n* `plot(expression)` - any gnuplot-supported mathematical expression\n\n*xdata*, *ydata* and *zdata* may be any type that implements\n`Indexable(Number)`. Chart dimensionality (2D or 3D) is inferred from\nthe data.\n\nAll `plot` methods/commands accept the optional named arguments\n*title*, *style*, *dashtype* (*dt*), *linecolor* (*lc*), *linewidth*\n(*lw*), *pointsize* (*ps*), *pointtype* (*pt*), *linestyle* (*ls*),\n*fillstyle* (*fs*) and *format*.\n\n*title* specifies the title of the plot in the chart key.\n\n*style* explicitly specifies the style of the plot (`:lines`,\n`:points`, etc.). Ishi will try to infer the style from the data and\nthe other named arguments (for example, if both *linewidth* and\n*pointsize* are provided, the style will be `:linespoints`).\n\nBy default, plots are rendered with solid lines. *dashtype* (*dt*)\nspecifies the pattern of dashes to use instead. *dashtype* may be an\narray of pairs of numbers that specify the length of a solid line\nfollowed by the length of an empty space (e.g. `[2, 3, 5, 7]`), or it\nmay be a string composed of . (dot), - (hyphen), \\_ (underscore) and\n(space), which is then converted into an array as follows: each \".\"\nbecomes `[2, 5]`, \"-\" becomes `[10, 10]`, \"\\_\" becomes `[20, 10]` and\n\" \" adds 10 to the previous empty value.\n\n*linecolor* specifies the color to use for lines and points. Colors\nmay be specified by name (e.g. \"red\", \"blue\", or \"green\") or by\nhexadecimal color value (e.g. \"#AARRGGBB\" or \"#RRGGBB\").\n\n*linewidth* and *pointsize* scale the width of lines and the size of\npoints, respectively. A value of 2.0 is twice as big as the default\nwidth or size.\n\nThe following code demonstrates the use of *dashtype*, *linecolor* and\n*linewidth*:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  plot(\"x + 4.0\", dashtype: \"-\", linewidth: 2)\n  plot(\"x + 3.0\", dashtype: \"_\", linewidth: 2)\n  plot(\"x + 2.0\", dashtype: \".\", linewidth: 2)\n  plot(\"x + 1.0\", dashtype: \"..._\", linewidth: 2)\n  plot(\"x + 0.0\", dashtype: [30, 10, 50, 10], linewidth: 2, linecolor: \"#88001100\")\nend\n```\n\n![lines](https://raw.githubusercontent.com/toddsundsted/ishi/e277adfe71bf8ad3ead70fab9b3736ed969608d7/etc/examples/2.png)\n\n*pointtype* selects the type of point to render. Available types\ndepend on the gnuplot terminal device used, but commonly supported\nvalues are . (dot), + (plus sign), x (multiplication sign), *\n(asterisk), s (square), o (circle), ^ (up triangle), and v (down\ntriangle) and d (diamond).\n\nThe following code demonstrates the use of *pointtype* and\n*pointsize*:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  plot([1, 2, 3, 4], [5, 6, 7, 8], pointtype: 1, pointsize: 2)\n  plot([1, 2, 3, 4], [4, 5, 6, 7], pointtype: \"o\", pointsize: 2)\n  plot([1, 2, 3, 4], [3, 4, 5, 6], pointtype: \"s\", pointsize: 2)\n  plot([1, 2, 3, 4], [2, 3, 4, 5], pointtype: \"^\", pointsize: 2)\n  plot([1, 2, 3, 4], [1, 2, 3, 4], pointtype: \"v\", pointsize: 2, linecolor: \"#88001100\")\nend\n```\n\n![points](https://raw.githubusercontent.com/toddsundsted/ishi/e277adfe71bf8ad3ead70fab9b3736ed969608d7/etc/examples/3.png)\n\nThe *format* argument is a short string used to specify color, point\nand line, simultaneously.\n\nColor is a letter from the set b (blue), g (green), r (red), c (cyan),\nm (magenta), y (yellow), k (black) or w (white). Point is a letter\nfrom the set . (dot), + (plus sign), x (multiplication sign), *\n(asterisk), s (square), c (circle), ^ (up triangle), v (down triangle)\nor d (diamond). Line may be - (solid line), -- (dashed line), !\n(dash-dot line) and : (dotted line).\n\nGiven these rules, the format string \"b\" is a solid blue line, \"or\" is\nred circles, \"^k:\" is black triangles connected by dotted black lines,\n\"g-\" is a solid green line and \"--\" is a dashed line.\n\n*format* may also be a single word color name or hexadecimal color\nvalue, in which case point and line may not be specified.\n\nReturning to the first example, the code uses *format* to customize\nthe plots:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  plot([1, 2, 3, 4, 5], [1.0, 1.4, 1.9, 2.4, 2.6], \"ko\", title: \"data\")\n  plot(\"0.4 * x + 0.7\", \"b--\")\nend\n```\n\nThe *format* \"ko\" could also be expressed explicitly (and much more\nverbosely) with the named arguments `linecolor: \"black\", pointtype: 7`,\nand the *format* \"b--\" with `linecolor: \"blue\", dashtype: 2`.\n\n### scatter\n\n`scatter` draws scatter plots. It takes data in several formats:\n* `scatter(xdata, ydata)` - x values in *xdata* and corresponding y values in *ydata*\n* `scatter(xdata, ydata, zdata)` - x values in *xdata*, y values in *ydata*, and z values in *zdata*\n\nChart dimensionality (2D or 3D) is inferred from the data. By default,\n`scatter` places a . (dot) at each point.\n\nAll `scatter` methods/commands accept the optional named arguments\n*title*, *style*, *dashtype* (*dt*), *linecolor* (*lc*), *linewidth*\n(*lw*), *pointsize* (*ps*), *pointtype* (*pt*), *linestyle* (*ls*) and\n*format*.\n\nThe following code demonstrates the use of *scatter*:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  scatter(xdata, zdata, lc: \"#4b03a1\")\n  scatter(ydata, zdata, lc: \"#b5367a\")\nend\n```\n\n![scatter](https://raw.githubusercontent.com/toddsundsted/ishi/e277adfe71bf8ad3ead70fab9b3736ed969608d7/etc/examples/4.png)\n\n### imshow\n\n`imshow` displays data as a pseudocolor, heatmapped image:\n* `imshow(data)` - *data* is two-dimensional scalar data, which will be rendered as an image\n\nThe following code demonstrates the use of *imshow*:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  palette(:inferno)\n  imshow(data)\n  margin(0, 0, 0, 0)\n  show_colorbox(false)\n  show_border(false)\n  show_xtics(false)\n  show_ytics(false)\n  show_key(false)\nend\n```\n\n![imshow](https://raw.githubusercontent.com/toddsundsted/ishi/e277adfe71bf8ad3ead70fab9b3736ed969608d7/etc/examples/5.png)\n\n### charts\n\n`charts` changes the number of charts in the figure:\n* `charts(rows, cols)` - *rows* and *cols* are the number of rows and columns in the figure\n\nBy default a figure has one chart. This call changes the number of\ncharts in the figure. The original chart is preserved and becomes the\nchart in the first row, first column of the new layout.\n\nWhen called without a block, `charts` returns the charts in the\nfigure.\n\n```crystal\nrequire \"ishi\"\n\nfigure = Ishi.new\ncharts = figure.charts(2, 2)\ncharts[0].plot([1, 2, 3, 4])\ncharts[1].plot([1, 1, 3, 2])\ncharts[2].plot([1, 1, 1, 1])\ncharts[3].plot([4, 3, 2, 1])\nfigure.show\n```\n\nWhen called with a block, `charts` Yields each chart as the default\nreceiver of the supplied block. Block arguments are *i* (the i-th\nchart in the figure), *row* and *col* (the row and column of the\nchart).\n\n```crystal\nrequire \"ishi\"\n\nfigure = Ishi.new\nfigure.charts(2, 2) do |i, row, col|\n  plot([1, 2, 3, 4].rotate(i), title: \"#{row},#{col}\")\nend\nfigure.show\n```\n\n### Non-numeric labels on the x-axis\n\n`xtics` sets non-numeric labels for positions on the x-axis.\n\nThe following code demonstrates the use of *xtics*:\n\n```crystal\nrequire \"ishi\"\n\nIshi.new do\n  x = [1, 2, 3]\n  y = [65, 30, 5]\n  plot(x, y, title: \"Visits\", style: :boxes, fs: 0.25)\n    .boxwidth(0.5)\n    .ylabel(\"Visits (%)\")\n    .xlabel(\"Device\")\n    .xtics({\n      1.0 =\u003e \"mobile\",\n      2.0 =\u003e \"desktop\",\n      3.0 =\u003e \"tablet\"\n    })\nend\n```\n\n![xtics](https://raw.githubusercontent.com/toddsundsted/ishi/c3326585b3c4c406f47938e64e76797ea8f8af29/etc/examples/7.png)\n\n### MXNet::NDArray\n\n`MXNet::NDArray` is an indexable, multi-dimensional array that\nefficiently supports numerical operations (transposition, matrix\nmultiplication, etc.).\n\nAll appropriate methods/commands accept instances of `MXNet::NDArray`\nwith the correct shape (1-dimensional vectors for x-values, for\nexample).\n\n```crystal\nrequire \"ishi\"\nrequire \"mxnet\"\n\nm = MXNet::NDArray.array(\n  [[0, 0, 1, 1],\n   [1, 2, 3, 4],\n   [1, 1, 2, 2]]\n)\n\nfigure = Ishi.new\ncharts = figure.charts(1, 2)\ncharts[0].plot(m[0], m[1], m[2])\ncharts[1].plot(m[.., 0], m[.., 1], m[.., 2])\nfigure.show\n```\n\nSee [MXNet.cr](https://github.com/toddsundsted/mxnet.cr) for more\ninformation on the complete library.\n\n### Extensions\n\nBy default, Ishi pops open a window to display charts. However, Ishi\ncomes with extensions that render charts as text, HTML, PNG or inline\nimages in the terminal; or that write to other `IO` destinations.\nNote: terminal image display only works with\n[ITerm2](https://www.iterm2.com/).\n\nTo plot the *sin(x)* function as text:\n\n```crystal\nrequire \"ishi/text\" # or \"ishi/html\" or \"ishi/iterm2\"\n\nIshi.new do\n  plot(\"sin(x)\")\nend\n```\n\nThis produces:\n\n```\n    1 +--------------------------------------------------------------------+\n      |                *  *              +  *  **         +       *  *     |\n  0.8 |-+             *   *                 *    *          sin(x* *******-|\n      |              *     *                *    *               *    *    |\n  0.6 |-+            *      *              *     *               *     * +-|\n      |              *      *             *       *             *       *  |\n  0.4 |*+            *      *             *       *             *       *+-|\n      |*            *        *            *        *           *        *  |\n  0.2 |*+           *        *            *        *           *        *+-|\n      | *          *          *          *         *          *          * |\n    0 |-*          *          *          *         *          *          *-|\n      |  *         *          *         *           *         *           *|\n -0.2 |-+*         *          *         *           *         *          +*|\n      |  *        *            *       *             *       *            *|\n -0.4 |-+*        *            *       *             *       *           +*|\n      |   *      *              *      *             *      *              |\n -0.6 |-+ *     *               *     *              *      *            +-|\n      |    *    *               *     *               *     *              |\n -0.8 |-+   *   *                *   *                 *   *             +-|\n      |     *  *       +         **  *   +             *  *                |\n   -1 +--------------------------------------------------------------------+\n     -10              -5                 0                5                10\n```\n\nYou can pass in an `IO` instance. Chart data will be written to the\n`IO` instance instead of `STDOUT`.\n\n```crystal\nrequire \"ishi/text\" # or \"ishi/html\" or \"ishi/png\"\n\nio = IO::Memory.new\n\nIshi.new(io) do\n  plot(\"sin(x)\")\nend\n```\n\n## Contributors\n\n- [Todd Sundsted](https://github.com/toddsundsted) - creator and maintainer\n- [lbarasti](https://github.com/lbarasti) - contributor\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoddsundsted%2Fishi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoddsundsted%2Fishi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoddsundsted%2Fishi/lists"}