Skip to content

Commit

Permalink
Merge pull request #22 from BigThinkcode/legend_areal
Browse files Browse the repository at this point in the history
Solution to bring Legends to Areal Plots
  • Loading branch information
Sadique-The-Alchemist authored Dec 19, 2024
2 parents 92a3536 + d3225cd commit 2022924
Show file tree
Hide file tree
Showing 19 changed files with 328 additions and 97 deletions.
26 changes: 13 additions & 13 deletions lib/matplotex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ defmodule Matplotex do
"""

@spec legend(Figure.t(), keyword() | map()) :: Figure.t()
def legend(figure, opts) when is_map(opts) do
Figure.add_legend(figure, opts)
end

def legend(figure, [h | _t] = opts) when is_tuple(h) do
params = Enum.into(opts, %{})
Figure.add_legend(figure, params)
end

def legend(figure, labels) when is_list(labels) do
Figure.add_legend(figure, %{labels: labels})
end
# @spec legend(Figure.t(), keyword() | map()) :: Figure.t()
# def legend(figure, opts) when is_map(opts) do
# Figure.add_legend(figure, opts)
# end

# def legend(figure, [h | _t] = opts) when is_tuple(h) do
# params = Enum.into(opts, %{})
# Figure.add_legend(figure, params)
# end

# def legend(figure, labels) when is_list(labels) do
# Figure.add_legend(figure, %{labels: labels})
# end

@doc """
Function to update figure params
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotex/element/circle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule Matplotex.Element.Circle do
type="#{circle.type}"
cx="#{get_cx(circle)}px"
cy="#{get_cy(circle)}px"
r="#{circle.r}"
r="#{get_r(circle)}"
fill="#{circle.fill}" stroke="#{circle.stroke}"
stroke_width="#{circle.stroke_width}"
>
Expand All @@ -31,7 +31,7 @@ defmodule Matplotex.Element.Circle do

def get_cx(%{cx: x}), do: to_pixel(x)
def get_cy(%{cy: y}), do: to_pixel(y)

def get_r(%{r: r}), do: to_pixel(r)
@impl Element
def flipy(%__MODULE__{cy: y} = circle, height) do
%__MODULE__{circle | cy: height - y}
Expand Down
65 changes: 65 additions & 0 deletions lib/matplotex/element/legend.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule Matplotex.Element.Legend do
alias Matplotex.Element.Label
alias Matplotex.Element

use Element

@stroke_width 1
@stroke "rgba(0,0,0,0)"
@legend_size 20 / 96
@label_type "legend.label"
defstruct [
:type,
:x,
:y,
:color,
:label,
:handle,
width: @legend_size,
height: @legend_size,
label_margin: @legend_size,
stroke: @stroke,
stroke_width: @stroke_width
]

@impl Element
def assemble(legend) do
"""
#{handle(legend)}
#{Element.assemble(legend.label)}
"""
end

@impl Element
def flipy(%__MODULE__{y: y} = legend, height) do
%__MODULE__{legend | y: height - y, label: Label.flipy(legend.label, height)}
end

defp handle(%__MODULE__{handle: %handle_element{} = handle}) do
handle_element.assemble(handle)
end

def with_label(
%__MODULE__{
label: text,
x: x,
y: y,
width: width,
height: height
} = legend,
legend_font,
padding
) do
%{
legend
| label:
%Label{
x: x + width + padding,
y: y + height / 2,
text: text,
type: @label_type
}
|> Label.cast_label(legend_font)
}
end
end
1 change: 1 addition & 0 deletions lib/matplotex/element/polygon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Matplotex.Element.Polygon do
~s(
<polygon points="#{assemble_point(polygon)}"
fill="#{polygon.fill}"
type="#{polygon.type}"
/>
)
end
Expand Down
19 changes: 10 additions & 9 deletions lib/matplotex/element/rad_legend.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,19 @@ defmodule Matplotex.Element.RadLegend do
y: y,
width: width,
height: height
} = legend, legend_font
} = legend,
legend_font
) do

%{
legend
| label: %Label{
x: x + width ,
y: y + height / 2,
text: text,
type: @label_type
}
|> Label.cast_label(legend_font)
| label:
%Label{
x: x + width,
y: y + height / 2,
text: text,
type: @label_type
}
|> Label.cast_label(legend_font)
}
end
end
3 changes: 1 addition & 2 deletions lib/matplotex/figure.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ defmodule Matplotex.Figure do
def new(opts) do
struct(__MODULE__, opts)
end

# TODO: put error message in error
# def put_error(figure, opts) do

Expand Down Expand Up @@ -114,6 +115,4 @@ defmodule Matplotex.Figure do
defp update_rc_params(_, _) do
raise Matplotex.InputError, keys: [:rc_params], message: "Invalid Input"
end


end
27 changes: 15 additions & 12 deletions lib/matplotex/figure/areal.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ defmodule Matplotex.Figure.Areal do
@callback create(struct(), any(), keyword()) :: struct()
@callback materialize(struct()) :: struct()
@callback plotify(number(), tuple(), number(), number(), list(), atom()) :: number()
@callback with_legend_handle(struct(), struct()) :: struct()
defmacro __using__(_) do
quote do
@behaviour Matplotex.Figure.Areal
alias Matplotex.Figure.TwoD
alias Matplotex.Figure.Dimension
alias Matplotex.Figure.Coords
alias Matplotex.Figure.Text
alias Matplotex.Figure.Legend

import Matplotex.Figure.Areal, only: [transformation: 7, do_transform: 6]
import Matplotex.Blueprint.Frame
Expand Down Expand Up @@ -154,6 +154,7 @@ defmodule Matplotex.Figure.Areal do
|> Cast.cast_spines_by_region()
|> Cast.cast_label_by_region()
|> Cast.cast_title_by_region()
|> Cast.cast_legends()
end

defp update_tick(axes, tick) do
Expand Down Expand Up @@ -255,7 +256,6 @@ defmodule Matplotex.Figure.Areal do

def set_region_title(figure), do: figure


def set_region_legend(
%Figure{
axes:
Expand All @@ -274,7 +274,7 @@ defmodule Matplotex.Figure.Areal do
region_x_width_after_legend = region_x_width - region_legend_width

{x_region_legend, y_region_legend} =
Algebra.transform_given_point(-region_legend_width, -region_title_height, rx, ty, 0)
Algebra.transform_given_point(-region_legend_width, -region_title_height, rx, ty)

%Figure{
figure
Expand All @@ -294,17 +294,19 @@ defmodule Matplotex.Figure.Areal do
}
}
end

def set_region_legend(figure), do: figure

def set_region_content(
%Figure{
axes:
%{
region_x: %Region{x: x_region_x, width: region_x_width},
region_y: %Region{y: y_region_y, height: region_y_height},
region_content: region_content
} = axes
} = figure
) do
%Figure{
axes:
%{
region_x: %Region{x: x_region_x, width: region_x_width},
region_y: %Region{y: y_region_y, height: region_y_height},
region_content: region_content
} = axes
} = figure
) do
%Figure{
figure
| axes: %{
Expand All @@ -319,6 +321,7 @@ defmodule Matplotex.Figure.Areal do
}
}
end

def set_region_content(figure), do: figure
end
end
Expand Down
10 changes: 9 additions & 1 deletion lib/matplotex/figure/areal/bar_chart.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule Matplotex.Figure.Areal.BarChart do
import Matplotex.Figure.Numer
alias Matplotex.Figure.Areal.Region
alias Matplotex.Element.Legend
alias Matplotex.Figure.Dataset
alias Matplotex.Element.Rect
alias Matplotex.Figure.RcParams
Expand All @@ -12,7 +13,6 @@ defmodule Matplotex.Figure.Areal.BarChart do
@xmin_value 0

frame(
legend: %Legend{},
coords: %Coords{},
dimension: %Dimension{},
tick: %TwoD{},
Expand Down Expand Up @@ -100,6 +100,14 @@ defmodule Matplotex.Figure.Areal.BarChart do
value * s + transition - minl * s
end

@impl Areal
def with_legend_handle(
%Legend{x: x, y: y, color: color, width: width, height: height} = legend,
_dataset
) do
%Legend{legend | handle: %Rect{x: x, y: y, color: color, width: width, height: height}}
end

def generate_ticks([{_l, _v} | _] = data) do
{data, min_max(data)}
end
Expand Down
25 changes: 24 additions & 1 deletion lib/matplotex/figure/areal/line_plot.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Matplotex.Figure.Areal.LinePlot do
alias Matplotex.Utils.Algebra
alias Matplotex.Figure.Areal.Region
alias Matplotex.Figure.Areal.Ticker
alias Matplotex.Figure.Marker
Expand All @@ -8,11 +9,11 @@ defmodule Matplotex.Figure.Areal.LinePlot do
alias Matplotex.Element.Line
alias Matplotex.Figure.Coords
alias Matplotex.Figure
alias Matplotex.Element.Legend

use Matplotex.Figure.Areal

frame(
legend: %Legend{},
coords: %Coords{},
dimension: %Dimension{},
tick: %TwoD{},
Expand Down Expand Up @@ -95,6 +96,28 @@ defmodule Matplotex.Figure.Areal.LinePlot do
value * s + transition - minl * s
end

@impl Areal
def with_legend_handle(
%Legend{x: x, y: y, color: color, width: marker_size} = legend,
%Dataset{linestyle: linestyle}
) do
{x2, y2} = Algebra.transform_given_point(x, y, marker_size, marker_size / 2)

%Legend{
legend
| handle: %Line{
type: "plot.line",
x1: x,
y1: y + marker_size / 2,
x2: x2,
y2: y2,
stroke: color,
fill: color,
linestyle: linestyle
}
}
end

def generate_ticks([{_l, _v} | _] = data) do
{data, min_max(data)}
end
Expand Down
11 changes: 9 additions & 2 deletions lib/matplotex/figure/areal/scatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Matplotex.Figure.Areal.Scatter do
alias Matplotex.Figure.Areal.Ticker
alias Matplotex.Figure.Marker
alias Matplotex.Figure.Dataset

alias Matplotex.Element.Legend
alias Matplotex.Figure.Areal
alias Matplotex.Figure.RcParams

Expand All @@ -13,7 +13,6 @@ defmodule Matplotex.Figure.Areal.Scatter do
use Areal

frame(
legend: %Legend{},
coords: %Coords{},
dimension: %Dimension{},
tick: %TwoD{},
Expand Down Expand Up @@ -136,6 +135,14 @@ defmodule Matplotex.Figure.Areal.Scatter do
value * s + transition - minl * s
end

@impl Areal
def with_legend_handle(
%Legend{x: x, y: y, color: color, width: marker_size} = legend,
%Dataset{marker: marker}
) do
%Legend{legend | handle: Marker.marker_legend(marker, x, y, color, marker_size)}
end

def generate_ticks([{_l, _v} | _] = data) do
{data, min_max(data)}
end
Expand Down
Loading

0 comments on commit 2022924

Please sign in to comment.