Skip to content

Commit

Permalink
fixed half of the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rdboyes committed Apr 2, 2024
1 parent 97f6af9 commit 4c430d3
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 76 deletions.
1 change: 1 addition & 0 deletions src/TidierPlots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ include("ggsave.jl")
include("labs.jl")
include("scales.jl")
include("themes.jl")
include("transforms.jl")
include("patchwork.jl")
include("show.jl")
include("util.jl")
Expand Down
103 changes: 43 additions & 60 deletions src/draw.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,29 @@ function Makie.SpecApi.Axis(plot::GGPlot)

# What type does the Makie argument expect?
# without a specified type here, arguments will pass "as is"

expected_type = Dict{String, Type}(
# Symbol
"marker" => Symbol,
"strokecolor" => Symbol,
"glowcolor" => Symbol,
"colormap" => Symbol,
"marker" => Symbol,
"strokecolor" => Symbol,
"glowcolor" => Symbol,
"colormap" => Symbol,
"yaxisposition" => Symbol,
"direction" => Symbol,
"direction" => Symbol,
# Float
"alpha" => Float32,
"markersize" => Float32,
"strokewidth" => Float32,
"glowwidth" => Float32,
"alpha" => Float32,
"markersize" => Float32,
"strokewidth" => Float32,
"glowwidth" => Float32,
# Integer
"bins" => Int64
"bins" => Int64
)

plot_list = Makie.PlotSpec[]
axis_options = Dict{Symbol, Any}()

for geom in plot.geoms
# use the dataframe specified in the geom if present, otherwise default to the ggplot one
# use the dataframe specified in the geom if present, otherwise use the ggplot one
plot_data = isnothing(geom.data) ? plot.data : geom.data

# inherit any aes specified at the ggplot level
Expand All @@ -56,35 +57,28 @@ function Makie.SpecApi.Axis(plot::GGPlot)
# which optional aesthetics were given?
optional_aes_given = [k for (k, v) in aes_dict if !(k in required_aes)]
visual_optional_aes = Dict{Symbol, Any}()

dont_categorize = ["text", "label"]

for a in optional_aes_given
if haskey(ggplot_to_makie_geom, a)
aes = Symbol(ggplot_to_makie_geom[a])
else
aes = Symbol(a)
end

if a in dont_categorize
column_data = String.(plot_data[!, aes_dict[a]])
# the name of the aes is translated to the makie term if needed
aes = haskey(ggplot_to_makie_geom, a) ? Symbol(ggplot_to_makie_geom[a]) : Symbol(a)

# if there is a specified column transformation, use it
# otherwise use cat_inseq for string-like columns and as_is for everything else
if haskey(geom.column_transformations, aes)
plottable_data = geom.column_transformations[aes](aes, plot_data)
elseif eltype(plot_data[!, aes_dict[a]]) <: Union{AbstractString, AbstractChar}
if haskey(plot.axis_options, "cat_inorder")
cat_column = plot_data[!, aes_dict[a]]
cat_array = CategoricalArray(cat_column,
levels = unique(cat_column),
ordered = true)
else
cat_array = CategoricalArray(plot_data[!, aes_dict[a]])
end
column_data = levelcode.(cat_array)
labels = levels(cat_array)
args_dict[a * "ticks"] = (1:length(labels), labels)
plottable_data = cat_inseq(aes, plot_data)
else
column_data = plot_data[!, aes_dict[a]]
plottable_data = as_is(aes, plot_data)
end

# if the transform has a label associated with it, pass that into axis_options
if !isnothing(plottable_data.label_target)
axis_options[label_target] = plottable_data.label_function(plottable_data.raw)
end

push!(visual_optional_aes, aes => column_data)
# add the transformed data to list to eventually be passed to the plots kwargs
push!(visual_optional_aes, aes => plottable_data.makie_function(plottable_data.raw))
end

# which ones were given as arguments?
Expand Down Expand Up @@ -112,28 +106,23 @@ function Makie.SpecApi.Axis(plot::GGPlot)
# make a Tuple that contains the columns from the data in their required order to pass to PlotSpec
visual_args_list = []

for req_aes in required_aes

if req_aes in dont_categorize
column_data = String.(plot_data[!, aes_dict[req_aes]])
elseif eltype(plot_data[!, aes_dict[req_aes]]) <: Union{AbstractString, AbstractChar}
if haskey(plot.axis_options, "cat_inorder")
cat_column = plot_data[!, aes_dict[req_aes]]
cat_array = CategoricalArray(cat_column, levels = unique(cat_column), ordered = true)
else
cat_array = CategoricalArray(plot_data[!, aes_dict[req_aes]])
end
column_data = levelcode.(cat_array)
labels = levels(cat_array)
axis_options[Symbol(req_aes * "ticks")] = (1:length(labels), labels)
for a in required_aes
aes = Symbol(a)
# if there is a specified column transformation, use it
# otherwise use cat_inseq for string-like columns and as_is for everything else
if haskey(geom.column_transformations, aes)
plottable_data = geom.column_transformations[aes](aes_dict[a], plot_data)
elseif eltype(plot_data[!, aes_dict[a]]) <: Union{AbstractString, AbstractChar}
plottable_data = cat_inseq(aes_dict[a], plot_data)
else
if plot_data isa DataFrame
column_data = plot_data[!, aes_dict[req_aes]]
else
column_data = plot_data[aes_dict[req_aes]]
end
plottable_data = as_is(aes_dict[a], plot_data)
end

# if the transform has a label associated with it, pass that into axis_options
if !isnothing(plottable_data[aes_dict[a]].label_target)
axis_options[plottable_data[aes_dict[a]].label_target] = plottable_data[aes_dict[a]].label_function(plottable_data[aes_dict[a]].raw)
end
push!(visual_args_list, column_data)
push!(visual_args_list, plottable_data[aes_dict[a]].makie_function(plottable_data[aes_dict[a]].raw))
end

args = Tuple([geom.visual, visual_args_list...])
Expand All @@ -144,12 +133,6 @@ function Makie.SpecApi.Axis(plot::GGPlot)
push!(plot_list, Makie.PlotSpec(args...; kwargs...))
end

# remove options from args_dict that are not meant for Makie

if haskey(plot.axis_options, "cat_inorder")
delete!(plot.axis_options, "cat_inorder")
end

# rename and correct types on all axis options

for (arg, value) in plot.axis_options
Expand Down
73 changes: 57 additions & 16 deletions src/transforms.jl
Original file line number Diff line number Diff line change
@@ -1,32 +1,63 @@
# transformation functions for aes specification
# they all should return a Dict that maps a aes symbol
# they all should return a Dict that maps an aes symbol
# to a PlottableData struct which contains

# - position: the data
# - raw: the data
# - makie_function: what should be done before data goes to the Makie arg
# - label_target: where should the labels go?
# - label_function: what should be done to data in "position" to display it
# - makie_function: what should be done before data goes to the Makie arg

struct PlottableData
position::Any
raw::Any
makie_function::Function
label_target::Union{Symbol, Nothing}
label_function::Any
end

# simplest one is as_is, which just gets the column
# simplest one is as_is, which just gets a column
# exactly as it is in the DataFrame

function as_is(target::Symbol, data::DataFrame)
return Dict{Symbol, PlottableData}(
target => PlottableData(data[!, target],
identity,
Symbol(String(target) * "ticks"),
Makie.automatic
target => PlottableData(
data[!, target], # get the column out of the dataframe
identity, # do nothing to it
nothing,
nothing
)
)
end

# verbatim has a similar goal, but for String columns

function convert_to(type::Type)
return function(target::Symbol, data::DataFrame)
return Dict{Symbol, PlottableData}(
target => PlottableData(
type.(data[!, target]),
identity,
nothing,
nothing
)
)
end
end

verbatim = convert_to(String)

function number_on_axis(target::Symbol, data::DataFrame)
return Dict{Symbol, PlottableData}(
target => PlottableData(
data[!, target], # get the column out of the dataframe
identity, # do nothing to it
Symbol(String(target) * "ticks"), # the axis label it will have, e.g. :xticks
Makie.automatic # calculate those ticks automatically
)
)
end



# categorical array handling options for String columns

function cat_inorder(target::Symbol, data::DataFrame)
Expand All @@ -36,8 +67,10 @@ function cat_inorder(target::Symbol, data::DataFrame)
ordered = true)
return Dict{Symbol, PlottableData}(
target => PlottableData(
levelcode.(cat_array),
x -> levels(x)
cat_array,
x -> levelcode.(x),
Symbol(String(target) * "ticks"),
x -> (1:length(levels(x)), levels(x))
)
)
end
Expand All @@ -46,8 +79,10 @@ function cat_inseq(target::Symbol, data::DataFrame)
cat_array = CategoricalArray(data[!, target])
return Dict{Symbol, PlottableData}(
target => PlottableData(
levelcode.(cat_array),
x -> levels(x)
cat_array,
x -> levelcode.(x),
Symbol(String(target) * "ticks"),
x -> (1:length(levels(x)), levels(x))
)
)
end
Expand All @@ -59,8 +94,14 @@ function kernel_density_2d(x::Symbol, y::Symbol, data::DataFrame)
k = kde((data[!, x], data[!, y]))

return Dict{Symbol, PlottableData}(
:x => PlottableData(k.x, identity),
:y => PlottableData(k.y, identity),
:z => PlottableData(k.density, identity)
:x => PlottableData(k.x, identity,
:xticks,
Makie.automatic),
:y => PlottableData(k.y, identity,
:yticks,
Makie.automatic),
:z => PlottableData(k.density, identity,
:zticks,
Makie.automatic)
)
end

0 comments on commit 4c430d3

Please sign in to comment.