From 51e56787d6fae360f5fde0f2d96a920b5604ed77 Mon Sep 17 00:00:00 2001 From: Mohammed Sadique Date: Thu, 19 Dec 2024 19:06:01 +0530 Subject: [PATCH 1/3] plot options --- lib/matplotex/figure.ex | 4 ++ lib/matplotex/figure/areal/line_plot.ex | 3 ++ lib/matplotex/figure/areal/plot_options.ex | 32 ++++++++++++++++ lib/matplotex/figure/rc_params.ex | 7 +++- lib/matplotex/figure/two_d.ex | 12 ++++++ test/matplotex_test.exs | 44 ++++++++++++++++++++++ 6 files changed, 101 insertions(+), 1 deletion(-) diff --git a/lib/matplotex/figure.ex b/lib/matplotex/figure.ex index b8d7129..892c629 100644 --- a/lib/matplotex/figure.ex +++ b/lib/matplotex/figure.ex @@ -3,6 +3,8 @@ defmodule Matplotex.Figure do @row_column_default 1 @margin_default 0.05 @figsize {10, 6} + + @restricted_keys [:axes, :element, :valid?, :rc_params, :errors] defstruct [ :id, :axes, @@ -32,6 +34,8 @@ defmodule Matplotex.Figure do struct(__MODULE__, opts) end + def restricted_keys(), do: @restricted_keys + # TODO: put error message in error # def put_error(figure, opts) do diff --git a/lib/matplotex/figure/areal/line_plot.ex b/lib/matplotex/figure/areal/line_plot.ex index 9412177..2092bb2 100644 --- a/lib/matplotex/figure/areal/line_plot.ex +++ b/lib/matplotex/figure/areal/line_plot.ex @@ -1,4 +1,5 @@ defmodule Matplotex.Figure.Areal.LinePlot do + alias Matplotex.Figure.Areal.PlotOptions alias Matplotex.Utils.Algebra alias Matplotex.Figure.Areal.Region alias Matplotex.Figure.Areal.Ticker @@ -38,7 +39,9 @@ defmodule Matplotex.Figure.Areal.LinePlot do dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) datasets = data ++ [dataset] xydata = flatten_for_data(datasets) + %Figure{figure | axes: %{axes | data: xydata, dataset: datasets}} + |> PlotOptions.set_options_in_figure(opts) end @impl Areal diff --git a/lib/matplotex/figure/areal/plot_options.ex b/lib/matplotex/figure/areal/plot_options.ex index 77b14c7..a06f6ec 100644 --- a/lib/matplotex/figure/areal/plot_options.ex +++ b/lib/matplotex/figure/areal/plot_options.ex @@ -1,4 +1,5 @@ defmodule Matplotex.Figure.Areal.PlotOptions do + alias ElixirLS.LanguageServer.Providers.Completion.Reducers.Struct alias Matplotex.Figure alias Matplotex.Figure.TwoD alias Matplotex.Figure.RcParams @@ -99,6 +100,37 @@ defmodule Matplotex.Figure.Areal.PlotOptions do |> set_options_in_rc_params_struct(options) end + def set_options_in_figure(%Figure{} = figure, opts) do + figure + |> cast_figure(opts) + |> cast_axes(opts) + |> cast_rc_params(opts) + end + + defp cast_figure(figure, opts) do + struct(figure, opts) + end + + defp cast_axes(%Figure{axes: axes} = figure, opts) do + %Figure{figure | axes: axes |> struct(opts) |> cast_two_d_structs(opts)} + end + + defp cast_two_d_structs(%{label: label, tick: tick, limit: limit} = axes, opts) + when is_map(opts) do + %{ + axes + | label: TwoD.update(label, opts, :label), + tick: TwoD.update(tick, opts, :tick), + limit: TwoD.update(limit, opts, :limit) + } + end + + defp cast_two_d_structs(axes, opts), do: cast_two_d_structs(axes, Enum.into(opts, %{})) + + defp cast_rc_params(%Figure{rc_params: rc_params} = figure, opts) do + %Figure{figure | rc_params: rc_params |> RcParams.update_with_font(opts) |> struct(opts)} + end + defp set_options_in_figure_struct(%Figure{} = figure, %__MODULE__{ figsize: figsize, figrows: figrows, diff --git a/lib/matplotex/figure/rc_params.ex b/lib/matplotex/figure/rc_params.ex index 5308a80..2c7291a 100644 --- a/lib/matplotex/figure/rc_params.ex +++ b/lib/matplotex/figure/rc_params.ex @@ -128,7 +128,7 @@ defmodule Matplotex.Figure.RcParams do y_label_font end - def update_with_font(rc_params, params) do + def update_with_font(rc_params, params) when is_map(params) do rc_params |> update_font(params, :x_label) |> update_font(params, :y_label) @@ -137,6 +137,11 @@ defmodule Matplotex.Figure.RcParams do |> update_font(params, :title) end + def update_with_font(rc_params, params) do + params = Enum.into(params, %{}) + update_with_font(rc_params, params) + end + defp update_font( rc_params, params, diff --git a/lib/matplotex/figure/two_d.ex b/lib/matplotex/figure/two_d.ex index 4429a2b..74b2496 100644 --- a/lib/matplotex/figure/two_d.ex +++ b/lib/matplotex/figure/two_d.ex @@ -1,3 +1,15 @@ defmodule Matplotex.Figure.TwoD do defstruct [:x, :y] + + def update(twod, opts, context) do + %__MODULE__{ + twod + | x: fetch_from_opts(opts, :x, context), + y: fetch_from_opts(opts, :y, context) + } + end + + defp fetch_from_opts(opts, key, context) do + Map.get(opts, :"#{key}_#{context}") + end end diff --git a/test/matplotex_test.exs b/test/matplotex_test.exs index 999671f..cc8ae0f 100644 --- a/test/matplotex_test.exs +++ b/test/matplotex_test.exs @@ -145,4 +145,48 @@ defmodule MatplotexTest do assert height == fheight - fheight * margin * 2 end end + + describe "with plot options" do + test "updates the values according to the plot options in line_plot" do + x = [1, 3, 7, 4, 2, 5, 6] + y = [1, 3, 7, 4, 2, 5, 6] + + options = [ + x_label: "X Axis", + y_label: "Y Axis", + title: "The Plot Title", + x_ticks: [1, 2, 3, 4, 5, 6, 7], + y_ticks: [1, 2, 3, 4, 5, 6, 7], + x_tick_font_size: 12, + y_tick_font_size: 16, + title_font_size: 14, + x_label_font_size: 10, + y_label_font_size: 10, + title_font_size: 14, + line_width: 2, + figsize: {10, 10}, + x_limit: [1, 7], + y_limit: [1, 7], + line_style: "_" + ] + + figure = Matplotex.plot(x, y, options) + + assert figure.axes.label.x == "X Axis" + assert figure.axes.label.y == "Y Axis" + assert figure.axes.title == "The Plot Title" + assert figure.axes.dataset |> List.first() |> Map.get(:x) == x + assert figure.axes.dataset |> List.first() |> Map.get(:y) == y + assert figure.axes.limit.x == [1, 7] + assert figure.axes.limit.y == [1, 7] + assert figure.rc_params.line_width == 2 + assert figure.figsize == {10, 10} + assert figure.rc_params.line_style == "_" + assert figure.rc_params.x_tick_font.font_size == 12 + assert figure.rc_params.y_tick_font.font_size == 16 + assert figure.rc_params.title_font.font_size == 14 + assert figure.rc_params.x_label_font.font_size == 10 + assert figure.rc_params.y_label_font.font_size == 10 + end + end end From 9ffb58860e39ba043159881298d5537a51677b54 Mon Sep 17 00:00:00 2001 From: Mohammed Sadique Date: Fri, 20 Dec 2024 18:19:02 +0530 Subject: [PATCH 2/3] draw plot with plot options --- lib/matplotex.ex | 8 +++ lib/matplotex/figure/areal/bar_chart.ex | 2 + lib/matplotex/figure/areal/line_plot.ex | 2 +- lib/matplotex/figure/areal/plot_options.ex | 13 +++- lib/matplotex/figure/areal/scatter.ex | 3 + lib/matplotex/figure/cast.ex | 1 - lib/matplotex/figure/lead.ex | 44 ++++++++---- lib/matplotex/figure/sketch.ex | 1 + lib/matplotex/figure/two_d.ex | 1 - lib/matplotex/helpers.ex | 72 +++++++++---------- test/matplotex_test.exs | 83 ++++++++++++++++++++++ 11 files changed, 173 insertions(+), 57 deletions(-) diff --git a/lib/matplotex.ex b/lib/matplotex.ex index 7d48036..7d68157 100644 --- a/lib/matplotex.ex +++ b/lib/matplotex.ex @@ -10,6 +10,14 @@ defmodule Matplotex do alias Matplotex.Figure alias Matplotex.Figure.Areal.BarChart + def bar(values, width) do + bar(width, values, width, []) + end + + def bar(values, width, opts) when is_list(opts) do + bar(width, values, width, opts) + end + def bar(pos, values, width) do bar(pos, values, width, []) end diff --git a/lib/matplotex/figure/areal/bar_chart.ex b/lib/matplotex/figure/areal/bar_chart.ex index 3932729..537e6f4 100644 --- a/lib/matplotex/figure/areal/bar_chart.ex +++ b/lib/matplotex/figure/areal/bar_chart.ex @@ -1,5 +1,6 @@ defmodule Matplotex.Figure.Areal.BarChart do import Matplotex.Figure.Numer + alias Matplotex.Figure.Areal.PlotOptions alias Matplotex.Figure.Areal.Region alias Matplotex.Element.Legend alias Matplotex.Figure.Dataset @@ -41,6 +42,7 @@ defmodule Matplotex.Figure.Areal.BarChart do | rc_params: %RcParams{white_space: width, y_padding: 0}, axes: %{axes | data: xydata, dataset: datasets} } + |> PlotOptions.set_options_in_figure(opts) end @impl Areal diff --git a/lib/matplotex/figure/areal/line_plot.ex b/lib/matplotex/figure/areal/line_plot.ex index 2092bb2..fd24fa4 100644 --- a/lib/matplotex/figure/areal/line_plot.ex +++ b/lib/matplotex/figure/areal/line_plot.ex @@ -32,7 +32,7 @@ defmodule Matplotex.Figure.Areal.LinePlot do def create( %Figure{axes: %__MODULE__{dataset: data} = axes} = figure, {x, y}, - opts \\ [] + opts ) do x = determine_numeric_value(x) y = determine_numeric_value(y) diff --git a/lib/matplotex/figure/areal/plot_options.ex b/lib/matplotex/figure/areal/plot_options.ex index a06f6ec..f00e314 100644 --- a/lib/matplotex/figure/areal/plot_options.ex +++ b/lib/matplotex/figure/areal/plot_options.ex @@ -1,5 +1,4 @@ defmodule Matplotex.Figure.Areal.PlotOptions do - alias ElixirLS.LanguageServer.Providers.Completion.Reducers.Struct alias Matplotex.Figure alias Matplotex.Figure.TwoD alias Matplotex.Figure.RcParams @@ -100,7 +99,9 @@ defmodule Matplotex.Figure.Areal.PlotOptions do |> set_options_in_rc_params_struct(options) end + @spec set_options_in_figure(Figure.t(), keyword()) :: Figure.t() def set_options_in_figure(%Figure{} = figure, opts) do + figure |> cast_figure(opts) |> cast_axes(opts) @@ -112,11 +113,19 @@ defmodule Matplotex.Figure.Areal.PlotOptions do end defp cast_axes(%Figure{axes: axes} = figure, opts) do - %Figure{figure | axes: axes |> struct(opts) |> cast_two_d_structs(opts)} + opts = Keyword.delete(opts, :label) + %Figure{figure | axes: axes |> struct(opts) |> cast_two_d_structs(opts) + # |>fulfill_tick_and_lim() + } end + # defp fulfill_tick_and_lim(%{tick: nil, limit: nil} = axes) do + + # end + defp cast_two_d_structs(%{label: label, tick: tick, limit: limit} = axes, opts) when is_map(opts) do + %{ axes | label: TwoD.update(label, opts, :label), diff --git a/lib/matplotex/figure/areal/scatter.ex b/lib/matplotex/figure/areal/scatter.ex index c9d559d..ec6525c 100644 --- a/lib/matplotex/figure/areal/scatter.ex +++ b/lib/matplotex/figure/areal/scatter.ex @@ -1,4 +1,5 @@ defmodule Matplotex.Figure.Areal.Scatter do + alias Matplotex.Figure.Areal.PlotOptions alias Matplotex.Figure.Areal.Region alias Matplotex.Figure.Areal.Ticker alias Matplotex.Figure.Marker @@ -32,7 +33,9 @@ defmodule Matplotex.Figure.Areal.Scatter do dataset = Dataset.cast(%Dataset{x: x, y: y}, opts) datasets = data ++ [dataset] xydata = flatten_for_data(datasets) + %Figure{figure | axes: %{axes | data: xydata, dataset: datasets}} + |> PlotOptions.set_options_in_figure(opts) end @impl Areal diff --git a/lib/matplotex/figure/cast.ex b/lib/matplotex/figure/cast.ex index 54f3eb7..a6057f7 100644 --- a/lib/matplotex/figure/cast.ex +++ b/lib/matplotex/figure/cast.ex @@ -89,7 +89,6 @@ defmodule Matplotex.Figure.Cast do } = figure ) do # Convert to the svg plane - {left_x, bottom_y} = Algebra.flip_y_coordinate({content_x, content_y}) {right_x, top_y} = diff --git a/lib/matplotex/figure/lead.ex b/lib/matplotex/figure/lead.ex index 5fa0ec2..2fde686 100644 --- a/lib/matplotex/figure/lead.ex +++ b/lib/matplotex/figure/lead.ex @@ -64,9 +64,10 @@ defmodule Matplotex.Figure.Lead do } = axes } = figure ) do + + {x_ticks, x_lim} = maybe_generate_ticks(x_ticks, x_lim, x_data, width) {y_ticks, y_lim} = maybe_generate_ticks(y_ticks, y_lim, y_data, height) - %Figure{ figure | axes: %{ @@ -78,28 +79,38 @@ defmodule Matplotex.Figure.Lead do end defp maybe_generate_ticks(ticks, limit, data, number_of_ticks) do - if is_nil(ticks) || length(ticks) < 3 do - generate_ticks(limit, data, ceil(number_of_ticks)) - else - {ticks, limit} + + cond do + is_nil(ticks) || length(ticks) < 3 -> + generate_ticks(limit, data, ceil(number_of_ticks)) + is_nil(limit) -> + {ticks, generate_limit(data)} + true -> + {ticks, limit} + end end defp generate_ticks(nil, data, number_of_ticks) do - {min, upper_limit} = Enum.min_max(data) + data + |>generate_limit() + |>generate_ticks(data, number_of_ticks) + end + + + defp generate_ticks({lower_limit, upper_limit} = lim, _data, number_of_ticks) do + {lower_limit |> Nx.linspace(upper_limit, n: number_of_ticks) |> Nx.to_list(), lim} + end + defp generate_limit(data) do + {min, upper_limit} = Enum.min_max(data) lower_limit = if min < 0 do min else 0 end - - generate_ticks({lower_limit, upper_limit}, data, number_of_ticks) - end - - defp generate_ticks({lower_limit, upper_limit} = lim, _data, number_of_ticks) do - {lower_limit |> Nx.linspace(upper_limit, n: number_of_ticks) |> Nx.to_list(), lim} + {lower_limit, upper_limit} end defp set_region_xy( @@ -124,6 +135,7 @@ defmodule Matplotex.Figure.Lead do ) do space_for_ylabel = height_required_for_text(y_label_font, y_label) y_tick = Enum.max_by(y_ticks, &tick_length(&1)) + space_for_yticks = length_required_for_text(y_tick_font, y_tick) space_required_for_region_y = @@ -352,8 +364,12 @@ defmodule Matplotex.Figure.Lead do rotation: 0 }, text - ), - do: tick_length(text) * to_number(font_size) * (pt_to_inch_ratio / 2) + flate + ) + do + text_size = tick_length(text) * to_number(font_size) * (pt_to_inch_ratio / 2) + offset_for_text_length = ((1/tick_length(text)) * (pt_to_inch_ratio/2) * to_number(font_size)) + text_size + offset_for_text_length + flate + end def length_required_for_text( %Font{ diff --git a/lib/matplotex/figure/sketch.ex b/lib/matplotex/figure/sketch.ex index 9f6d71b..b2c9d34 100644 --- a/lib/matplotex/figure/sketch.ex +++ b/lib/matplotex/figure/sketch.ex @@ -3,6 +3,7 @@ defmodule Matplotex.Figure.Sketch do @dpi 96 def call({stream, %Figure{figsize: {width, height}}}) do + stream |> Stream.map(fn %module{} = elem -> elem = module.flipy(elem, height) diff --git a/lib/matplotex/figure/two_d.ex b/lib/matplotex/figure/two_d.ex index 74b2496..e958df6 100644 --- a/lib/matplotex/figure/two_d.ex +++ b/lib/matplotex/figure/two_d.ex @@ -8,7 +8,6 @@ defmodule Matplotex.Figure.TwoD do y: fetch_from_opts(opts, :y, context) } end - defp fetch_from_opts(opts, key, context) do Map.get(opts, :"#{key}_#{context}") end diff --git a/lib/matplotex/helpers.ex b/lib/matplotex/helpers.ex index a9e2784..b08dd0b 100644 --- a/lib/matplotex/helpers.ex +++ b/lib/matplotex/helpers.ex @@ -18,44 +18,6 @@ defmodule Matplotex.Helpers do :ok end - def pie_chart_params() do - %{ - "id" => "chart-container", - "dataset" => [280, 45, 133, 152, 278, 221, 56], - "labels" => ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - "color_palette" => ["#f66", "pink", "orange", "gray", "#fcc", "green", "#0f0"], - "width" => 700, - "height" => 400, - "margin" => 15, - "legends" => true - } - end - - def lineplot_params() do - %{ - "id" => "line-plot", - "dataset" => [ - [1, 9, 8, 4, 6, 5, 3], - [1, 6, 5, 3, 3, 8, 6] - ], - "x_labels" => ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], - "y_labels" => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - "width" => 700, - "height" => 400, - "x_margin" => 20, - "y_margin" => 10, - "x_label_offset" => 40, - "y_label_offset" => 40, - "y_scale" => 1, - "x_scale" => 1, - "color_palette" => ["red", "green"], - "type" => "line_chart", - "x_label" => "Days", - "y_label" => "Count", - "line_width" => 3 - } - end - def line_plot() do x = [1, 2, 3, 4, 6, 6, 7] y = [1, 3, 4, 4, 5, 6, 7] @@ -91,6 +53,40 @@ defmodule Matplotex.Helpers do |> copy() end + def line_plot_by_options() do + x = [1, 2, 3, 4, 6, 6, 7] + y = [1, 3, 4, 4, 5, 6, 7] + + frame_width = 6 + frame_height = 6 + size = {frame_width, frame_height} + margin = 0.05 + font_size = "16pt" + title_font_size = "18pt" + ticks = [0, 1, 2, 3, 4, 5, 6, 7] + + x + |> Matplotex.plot(y, + figsize: size, + margin: margin, + title: "The plot title", + x_label: "X Axis", + y_label: "Y Axis", + x_tick: ticks, + y_tick: ticks, + x_limit: {0, 7}, + y_limit: {0, 7}, + x_tick_font_size: font_size, + y_tick_font_size: font_size, + title_font_size: title_font_size, + x_label_font_size: font_size, + y_label_font_size: font_size, + y_tick_font_text_anchor: "start" + ) + |> Matplotex.show() + |> copy() + end + def line_plotc() do x = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] y = [1, 3, 4, 4, 5, 6, 7] diff --git a/test/matplotex_test.exs b/test/matplotex_test.exs index cc8ae0f..fbd051e 100644 --- a/test/matplotex_test.exs +++ b/test/matplotex_test.exs @@ -189,4 +189,87 @@ defmodule MatplotexTest do assert figure.rc_params.y_label_font.font_size == 10 end end + + test "updates the values according to the plot options in bar_chart" do + values = [1, 3, 7, 4, 2, 5, 6] + width = 0.22 + + options = [ + x_label: "X Axis", + y_label: "Y Axis", + title: "The Plot Title", + x_ticks: [1, 2, 3, 4, 5, 6, 7], + y_ticks: [1, 2, 3, 4, 5, 6, 7], + x_tick_font_size: 12, + y_tick_font_size: 16, + title_font_size: 14, + x_label_font_size: 10, + y_label_font_size: 10, + title_font_size: 14, + line_width: 2, + figsize: {10, 10}, + x_limit: [1, 7], + y_limit: [1, 7], + line_style: "_" + ] + + figure = Matplotex.bar(values, width, options) + + assert figure.axes.label.x == "X Axis" + assert figure.axes.label.y == "Y Axis" + assert figure.axes.title == "The Plot Title" + assert figure.axes.dataset |> List.first() |> Map.get(:y) == values + assert figure.axes.limit.x == [1, 7] + assert figure.axes.limit.y == [1, 7] + assert figure.rc_params.line_width == 2 + assert figure.figsize == {10, 10} + assert figure.rc_params.line_style == "_" + assert figure.rc_params.x_tick_font.font_size == 12 + assert figure.rc_params.y_tick_font.font_size == 16 + assert figure.rc_params.title_font.font_size == 14 + assert figure.rc_params.x_label_font.font_size == 10 + assert figure.rc_params.y_label_font.font_size == 10 + end + + test "updates the values according to the plot options in scatter plot" do + x = [1, 3, 7, 4, 2, 5, 6] + y = [1, 3, 7, 4, 2, 5, 6] + + options = [ + x_label: "X Axis", + y_label: "Y Axis", + title: "The Plot Title", + x_ticks: [1, 2, 3, 4, 5, 6, 7], + y_ticks: [1, 2, 3, 4, 5, 6, 7], + x_tick_font_size: 12, + y_tick_font_size: 16, + title_font_size: 14, + x_label_font_size: 10, + y_label_font_size: 10, + title_font_size: 14, + line_width: 2, + figsize: {10, 10}, + x_limit: [1, 7], + y_limit: [1, 7], + line_style: "_" + ] + + figure = Matplotex.scatter(x, y, options) + + assert figure.axes.label.x == "X Axis" + assert figure.axes.label.y == "Y Axis" + assert figure.axes.title == "The Plot Title" + assert figure.axes.dataset |> List.first() |> Map.get(:x) == x + assert figure.axes.dataset |> List.first() |> Map.get(:y) == y + assert figure.axes.limit.x == [1, 7] + assert figure.axes.limit.y == [1, 7] + assert figure.rc_params.line_width == 2 + assert figure.figsize == {10, 10} + assert figure.rc_params.line_style == "_" + assert figure.rc_params.x_tick_font.font_size == 12 + assert figure.rc_params.y_tick_font.font_size == 16 + assert figure.rc_params.title_font.font_size == 14 + assert figure.rc_params.x_label_font.font_size == 10 + assert figure.rc_params.y_label_font.font_size == 10 + end end From 48c8d12151a4554194f578b94f84a539a4d602f3 Mon Sep 17 00:00:00 2001 From: Mohammed Sadique Date: Fri, 20 Dec 2024 18:20:08 +0530 Subject: [PATCH 3/3] format --- lib/matplotex/figure/areal/plot_options.ex | 11 +++++----- lib/matplotex/figure/lead.ex | 25 +++++++++++----------- lib/matplotex/figure/sketch.ex | 1 - lib/matplotex/figure/two_d.ex | 1 + 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/matplotex/figure/areal/plot_options.ex b/lib/matplotex/figure/areal/plot_options.ex index f00e314..ef6e3d1 100644 --- a/lib/matplotex/figure/areal/plot_options.ex +++ b/lib/matplotex/figure/areal/plot_options.ex @@ -101,7 +101,6 @@ defmodule Matplotex.Figure.Areal.PlotOptions do @spec set_options_in_figure(Figure.t(), keyword()) :: Figure.t() def set_options_in_figure(%Figure{} = figure, opts) do - figure |> cast_figure(opts) |> cast_axes(opts) @@ -114,9 +113,12 @@ defmodule Matplotex.Figure.Areal.PlotOptions do defp cast_axes(%Figure{axes: axes} = figure, opts) do opts = Keyword.delete(opts, :label) - %Figure{figure | axes: axes |> struct(opts) |> cast_two_d_structs(opts) - # |>fulfill_tick_and_lim() - } + + %Figure{ + figure + | axes: axes |> struct(opts) |> cast_two_d_structs(opts) + # |>fulfill_tick_and_lim() + } end # defp fulfill_tick_and_lim(%{tick: nil, limit: nil} = axes) do @@ -125,7 +127,6 @@ defmodule Matplotex.Figure.Areal.PlotOptions do defp cast_two_d_structs(%{label: label, tick: tick, limit: limit} = axes, opts) when is_map(opts) do - %{ axes | label: TwoD.update(label, opts, :label), diff --git a/lib/matplotex/figure/lead.ex b/lib/matplotex/figure/lead.ex index 2fde686..424067a 100644 --- a/lib/matplotex/figure/lead.ex +++ b/lib/matplotex/figure/lead.ex @@ -64,10 +64,9 @@ defmodule Matplotex.Figure.Lead do } = axes } = figure ) do - - {x_ticks, x_lim} = maybe_generate_ticks(x_ticks, x_lim, x_data, width) {y_ticks, y_lim} = maybe_generate_ticks(y_ticks, y_lim, y_data, height) + %Figure{ figure | axes: %{ @@ -79,37 +78,38 @@ defmodule Matplotex.Figure.Lead do end defp maybe_generate_ticks(ticks, limit, data, number_of_ticks) do - cond do is_nil(ticks) || length(ticks) < 3 -> generate_ticks(limit, data, ceil(number_of_ticks)) + is_nil(limit) -> {ticks, generate_limit(data)} + true -> {ticks, limit} - end end defp generate_ticks(nil, data, number_of_ticks) do data - |>generate_limit() - |>generate_ticks(data, number_of_ticks) + |> generate_limit() + |> generate_ticks(data, number_of_ticks) end - defp generate_ticks({lower_limit, upper_limit} = lim, _data, number_of_ticks) do {lower_limit |> Nx.linspace(upper_limit, n: number_of_ticks) |> Nx.to_list(), lim} end defp generate_limit(data) do {min, upper_limit} = Enum.min_max(data) + lower_limit = if min < 0 do min else 0 end + {lower_limit, upper_limit} end @@ -364,12 +364,11 @@ defmodule Matplotex.Figure.Lead do rotation: 0 }, text - ) - do - text_size = tick_length(text) * to_number(font_size) * (pt_to_inch_ratio / 2) - offset_for_text_length = ((1/tick_length(text)) * (pt_to_inch_ratio/2) * to_number(font_size)) - text_size + offset_for_text_length + flate - end + ) do + text_size = tick_length(text) * to_number(font_size) * (pt_to_inch_ratio / 2) + offset_for_text_length = 1 / tick_length(text) * (pt_to_inch_ratio / 2) * to_number(font_size) + text_size + offset_for_text_length + flate + end def length_required_for_text( %Font{ diff --git a/lib/matplotex/figure/sketch.ex b/lib/matplotex/figure/sketch.ex index b2c9d34..9f6d71b 100644 --- a/lib/matplotex/figure/sketch.ex +++ b/lib/matplotex/figure/sketch.ex @@ -3,7 +3,6 @@ defmodule Matplotex.Figure.Sketch do @dpi 96 def call({stream, %Figure{figsize: {width, height}}}) do - stream |> Stream.map(fn %module{} = elem -> elem = module.flipy(elem, height) diff --git a/lib/matplotex/figure/two_d.ex b/lib/matplotex/figure/two_d.ex index e958df6..74b2496 100644 --- a/lib/matplotex/figure/two_d.ex +++ b/lib/matplotex/figure/two_d.ex @@ -8,6 +8,7 @@ defmodule Matplotex.Figure.TwoD do y: fetch_from_opts(opts, :y, context) } end + defp fetch_from_opts(opts, key, context) do Map.get(opts, :"#{key}_#{context}") end