Skip to content

s417-lama/plotly_ex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

You can try it by running the code below.

mix run examples/basic_line_plot.exs

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 \\ %{}, config \\ %{})

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

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

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(), plotly_js_url: string()]

filename: option

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.

plotly_js_url: option

URL of Plotly.js that should be loaded in the HTML header. Default value is "https://cdn.plot.ly/plotly-latest.min.js".

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>