Skip to content
Elixir wrapper for Plotly.js
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib
templates
test
.formatter.exs
.gitignore
README.md
mix.exs

README.md

Plotly.ex

Plotly.ex is an Elixir wrapper for Plotly.js. Plotly.ex enables you to plot interactive graphs using Elixir.

Usage

Let's show a basic line plot (https://plot.ly/javascript/line-charts/#basic-line-plot) as an example. The usage is almost the same as Plotly.js.

trace1 = %{
  x:    [1, 2, 3, 4],
  y:    [10, 15, 13, 17],
  type: "scatter",
}
trace2 = %{
  x:    [1, 2, 3, 4],
  y:    [16, 5, 11, 9],
  type: "scatter",
}

[trace1, trace2]
|> PlotlyEx.plot
|> PlotlyEx.show

By running this code, the graph below will be shown in your browser.

Note:
You cannot run the above elixir script by elixir command because Plotly.ex is not included in standard libraries. To run Elixir scripts with Mix dependencies, use s417-lama/erun.

basic_line_plot_web

You can save the graph as an SVG file by clicking "Save as SVG" button.

basic_line_plot

(optional) Crop SVG

The output SVG file may contain unnecessary margins. Once you convert SVG to PDF, you can use pdfcrop command.

$ cairosvg foo.svg -o foo.pdf
$ pdfcrop foo.pdf foo-cropped.pdf
$ pdf2svg foo-cropped.pdf foo-cropped.svg

(If you know any smarter way, please let me know.)

Install

def deps do
  [
    {:plotly_ex, git: "https://github.com/s417-lama/plotly_ex.git"},
  ]
end

Currently, it is not available on hex. If you like Plotly.ex, please encourage me to publish it on hex:)

API

Currently, Plotly.ex provides only 2 APIs.

PlotlyEx.plot(data, layout \\ %{})

Receives data and layout objects (map) and returns an HTML string. data and layout are converted to json and passed to Plotly.plot function in javascript.

See documents of Plotly.js to see how to set data and layout.

example:

iex> PlotlyEx.plot([%{type: "scatter", x: [1, 2], y: [3, 4]}]) |> IO.puts
<div class="plotly-ex">
  <div id="plotly-ex-body-771"></div>
  <script>
    Plotly.plot('plotly-ex-body-771', [{"type":"scatter","x":[1,2],"y":[3,4]}], {})
  </script>
</div>

You can use the result HTML string as a part of your HTML page.

PlotlyEx.show(plot_html, opts \\ [])

Receives an HTML string generated by PlotlyEx.plot/2 and shows it in web browsers.

opts :: [filename: string()]

If filename: option is set, the HTML is saved to the specified path.

If filename: option is not set, no output files are generated and the result is shown in browsers only once. Internally, it creates an one-time web server to avoid generating unnecessary temporary files (see below for more details).

example:

iex(3)> PlotlyEx.plot([%{type: "scatter", x: [1, 2], y: [3, 4]}]) |> PlotlyEx.show
listening on http://localhost:39865
accepted. quitting...
:ok

and the graph is shown in your browser automatically.

Implementation Notes

In fact, Plotly.ex just converts data to json and passes it to Plotly.js, and all of the plotting functions are provided by Plotly.js.

If filename is not specified, PlotlyEx.show/2 creates one-time web server to send the HTML to your browser. The server listens on http://localhost:<port> as shown in stderr, and the port is randomly chosen from avaliable ports. And then PlotlyEx.show/2 opens http://localhost:<port> in a browser. When the server receives a request, it sends the HTML as a response and shutdowns. Temporary files become unnecessary by doing so.

PlotlyEx.show/2 opens your browsers by using open or xdg-open command on your environment. If they don't exist, please manually open http://localhost:<port> in your browser.

If you want to use Plotly.ex in Phoenix

Add Plotly.ex as a dependency in mix.exs. Then you can plot as

<%= PlotlyEx.plot([%{type: "scatter", x: [1, 2], y: [3, 4]}]) |> raw() %>

in your template engine. (Please note that raw/1 is needed.)

Also, you should include plotly.js in your HTML header.

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
You can’t perform that action at this time.