Skip to content

Commit e90d277

Browse files
committed
Create comma sep lists from list of plots
1 parent cc2bcfb commit e90d277

File tree

6 files changed

+94
-26
lines changed

6 files changed

+94
-26
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ by adding `gnuplot` to your list of dependencies in `mix.exs`:
101101
```elixir
102102
def deps do
103103
[
104-
{:gnuplot, "~> 0.19.73"}
104+
{:gnuplot, "~> 0.19.86"}
105105
]
106106
end
107107
```

examples/atan_sin_dataset.exs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
defmodule AtanSin do
2+
import Gnuplot
3+
4+
@moduledoc "http://gnuplot.sourceforge.net/demo/simple.7.gnu"
5+
6+
def png, do: Path.join("docs", "atan_sin_dataset.PNG")
7+
8+
def target,
9+
do: [
10+
[:set, :term, :png, :size, '512,256', :font, "/Library/Fonts/FiraCode-Medium.ttf", 12],
11+
[:set, :output, png()]
12+
]
13+
14+
def commands,
15+
do: [
16+
[
17+
:plot,
18+
"-",
19+
:with,
20+
:lines,
21+
:title,
22+
"sin(x*20)*atan(x)"
23+
]
24+
]
25+
26+
def plot, do: plot(target() ++ commands(), [dataset()])
27+
28+
defp dataset do
29+
Enum.map(ffor(-30, 20, 800), fn x -> [x, :math.sin(x * 20) * :math.atan(x)] end)
30+
end
31+
32+
# defp dataset2 do
33+
# for x <- -30_000..20_000,
34+
# do: [x / 1000.0, :math.sin(x * 20 / 1000.0) * :math.atan(x / 1000.0)]
35+
# end
36+
37+
defp ffor(min, max, step), do: for(x <- min..max, dx <- 0..step, do: x + dx / step)
38+
end
39+
40+
# mix run examples/atan_sin_dataset.exs
41+
AtanSin.plot()

lib/gnuplot.ex

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,36 @@ defmodule Gnuplot do
22
@moduledoc """
33
Interface to the Gnuplot graphing library.
44
5-
Plot a sine wave:
5+
Plot a sine function where Gnuplot generates the samples:
66
77
Gnuplot.plot([
88
~w(set autoscale)a,
99
~w(set samples 800)a,
1010
[:plot, -30..20, 'sin(x*20)*atan(x)']
1111
])
1212
13+
Plot a sine function where your program generates the data:
14+
15+
Gnuplot.plot([
16+
[:plot, "-", :with, :lines :title, "sin(x*20)*atan(x)"]
17+
],
18+
[
19+
for x <- -30_000..20_000, do: [x / 1000.0 , :math.sin(x * 20 / 1000.0) * :math.atan(x / 1000.0) ]
20+
])
21+
1322
"""
1423

1524
alias Gnuplot.Commands
1625
import Gnuplot.Dataset
1726

1827
@doc """
19-
Transmit commands and data streams to gnuplot.
28+
Plot a function that has no dataset.
29+
"""
30+
@spec plot(list(term())) :: {:ok, String.t()} | {:error, term()}
31+
def plot(commands), do: plot(commands, [])
32+
33+
@doc """
34+
Transmit commands and datasets to Gnuplot.
2035
2136
## Examples
2237
@@ -45,32 +60,31 @@ defmodule Gnuplot do
4560
end
4661

4762
@doc """
48-
Plot a function that has no dataset.
63+
Find the gnuplot executable.
4964
"""
50-
@spec plot(list(term())) :: {:ok, String.t()} | {:error, term()}
51-
def plot(commands), do: plot(commands, [])
65+
@spec gnuplot_bin() :: {:error, :gnuplot_missing} | {:ok, :file.name()}
66+
def gnuplot_bin do
67+
case :os.find_executable(String.to_charlist("gnuplot")) do
68+
false -> {:error, :gnuplot_missing}
69+
path -> {:ok, path}
70+
end
71+
end
5272

53-
@doc """
54-
Build a comma separated list.
55-
"""
56-
def list(a), do: %Commands.List{xs: [a]}
73+
@doc "Build a comma separated list from a list of terms."
74+
def list(xs) when is_list(xs), do: %Commands.List{xs: xs}
5775

76+
@doc "Build a comma separated list of two terms."
5877
def list(a, b), do: %Commands.List{xs: [a, b]}
5978

79+
@doc "Build a comma separated list of three terms."
6080
def list(a, b, c), do: %Commands.List{xs: [a, b, c]}
6181

82+
@doc "Build a comma separated list of four terms."
6283
def list(a, b, c, d), do: %Commands.List{xs: [a, b, c, d]}
6384

85+
@doc "Build a comma separated list of five terms."
6486
def list(a, b, c, d, e), do: %Commands.List{xs: [a, b, c, d, e]}
6587

66-
@doc """
67-
Find the gnuplot executable.
68-
"""
69-
@spec gnuplot_bin() :: {:error, :gnuplot_missing} | {:ok, :file.name()}
70-
def gnuplot_bin do
71-
case :os.find_executable(String.to_charlist("gnuplot")) do
72-
false -> {:error, :gnuplot_missing}
73-
path -> {:ok, path}
74-
end
75-
end
88+
@doc "Build a comma separated list of six terms."
89+
def list(a, b, c, d, e, f), do: %Commands.List{xs: [a, b, c, d, e, f]}
7690
end

lib/gnuplot/commands.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ defmodule Gnuplot.Commands do
4242
end
4343

4444
defmodule List do
45-
@moduledoc "Comma separated lists"
45+
@moduledoc """
46+
Comma separated list.
47+
Most lists are joined with whitespace, however the plot and splot commands require multiple plots to be comma separated.
48+
"""
4649
defstruct xs: []
4750
end
4851

mix.exs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Gnuplot.MixProject do
44
def project do
55
[
66
app: :gnuplot,
7-
version: "0.19.73",
7+
version: "0.19.86",
88
elixir: "~> 1.6",
99
start_permanent: Mix.env() == :prod,
1010
description: "Interface between Elixir and Gnuplot graphing library",
@@ -27,10 +27,10 @@ defmodule Gnuplot.MixProject do
2727

2828
defp deps do
2929
[
30-
{:credo, "~> 1.0.2", only: [:dev, :test], runtime: false},
31-
{:dialyxir, "~> 1.0.0-rc.4", only: [:dev], runtime: false},
32-
{:ex_doc, ">= 0.0.0", only: :dev},
33-
{:mix_test_watch, "~> 0.8", only: :dev, runtime: false}
30+
{:credo, "~> 1.0.4", only: [:dev, :test], runtime: false},
31+
{:dialyxir, "~> 1.0.0-rc.5", only: [:dev], runtime: false},
32+
{:ex_doc, ">= 0.19.0", only: :dev},
33+
{:mix_test_watch, "~> 0.9", only: :dev, runtime: false}
3434
]
3535
end
3636

test/gnuplot_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ defmodule GnuplotTest do
4242
input |> D.format_datasets() |> Enum.to_list()
4343
end
4444

45+
test "Comma separated lists of plots using arity 2" do
46+
assert "plot a with lines,b with points" ==
47+
C.format([[:plot, G.list([:a, :with, :lines], [:b, :with, :points])]])
48+
end
49+
50+
test "Comma separated lists of plots using arity 1 and sublists" do
51+
assert "plot a with lines,b with points" ==
52+
C.format([[:plot, G.list([[:a, :with, :lines], [:b, :with, :points]])]])
53+
end
54+
4555
@tag gnuplot: true
4656
test "Gnuplot is installed" do
4757
assert {:ok, path} = G.gnuplot_bin()

0 commit comments

Comments
 (0)