diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 61ed152..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Documentation: https://github.com/JuliaCI/Appveyor.jl -environment: - matrix: - - julia_version: 1.0 - - julia_version: 1.7 - - julia_version: nightly -platform: - - x64 -cache: - - '%USERPROFILE%\.julia\artifacts' -matrix: - allow_failures: - - julia_version: nightly -branches: - only: - - main - - /release-.*/ -notifications: - - provider: Email - on_build_success: false - on_build_failure: false - on_build_status_changed: false -install: - - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) -build_script: - - echo "%JL_BUILD_SCRIPT%" - - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" -test_script: - - echo "%JL_TEST_SCRIPT%" - - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" -on_success: - - echo "%JL_CODECOV_SCRIPT%" - - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%" diff --git a/.cirrus.yml b/.cirrus.yml index ff9669f..fcbeeef 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,13 +1,15 @@ freebsd_instance: - image: freebsd-13-2 + image_family: freebsd-13-2 task: name: FreeBSD artifacts_cache: folder: ~/.julia/artifacts env: - JULIA_VERSION: 1.0 - JULIA_VERSION: 1.7 - JULIA_VERSION: nightly + matrix: + - JULIA_VERSION: 1.9 + - JULIA_VERSION: 1 + - JULIA_VERSION: nightly + allow_failures: $JULIA_VERSION == 'nightly' install_script: - sh -c "$(fetch https://raw.githubusercontent.com/ararslan/CirrusCI.jl/master/bin/install.sh -o -)" build_script: @@ -15,4 +17,4 @@ task: test_script: - cirrusjl test coverage_script: - - cirrusjl coverage codecov coveralls + - cirrusjl coverage codecov diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index af505d2..e8415bc 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -3,6 +3,7 @@ on: push: branches: - main + - dev tags: '*' pull_request: diff --git a/LICENSE b/LICENSE index 7e13b04..4cc881a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Eduard I. STAN, Giovanni PAGLIARINI, Federico MANZELLA +Copyright (c) 2023 Lorenzo Balboni, Federico Manzella, Giovanni Pagliarini, Eduard I. Stan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Project.toml b/Project.toml index fd282e7..6fac3d8 100644 --- a/Project.toml +++ b/Project.toml @@ -7,11 +7,11 @@ version = "0.1.0" Catch22 = "acdeb78f-3d39-4310-8fdf-6d75c17c6d5a" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +MultiData = "8cc5100c-b3d1-4f82-90cb-0ea93d317aba" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SimpleCaching = "71e1c77a-176e-49fd-a90f-f84a4a948e95" SoleBase = "4475fa32-7023-44a0-aa70-4813b230e492" -SoleData = "123f1ae1-6307-4526-ab5b-aab3a92a2b8c" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] diff --git a/README.md b/README.md index b8c14c2..a819b70 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# *SoleViz.jl* +# SoleViz.jl diff --git a/docs/Project.toml b/docs/Project.toml index eba4c66..95c1405 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,3 +1,6 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" SoleViz = "fc840457-d78a-47de-ac4f-ba01d7af495c" + +[compat] +Documenter = "1" diff --git a/docs/make.jl b/docs/make.jl index 251d6fd..dc1cc00 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -6,9 +6,10 @@ DocMeta.setdocmeta!(SoleViz, :DocTestSetup, :(using SoleViz); recursive=true) makedocs(; modules=[SoleViz], authors="Lorenzo Balboni, Federico Manzella, Giovanni Pagliarini, Eduard I. Stan", - repo="https://github.com/aclai-lab/SoleViz.jl/blob/{commit}{path}#{line}", + repo=Documenter.Remotes.GitHub("aclai-lab", "SoleViz.jl"), sitename="SoleViz.jl", format=Documenter.HTML(; + size_threshold = 4000000, prettyurls=get(ENV, "CI", "false") == "true", canonical="https://aclai-lab.github.io/SoleViz.jl", assets=String[], @@ -20,8 +21,7 @@ makedocs(; deploydocs(; repo = "github.com/aclai-lab/SoleViz.jl", - devbranch = "main", target = "build", branch = "gh-pages", - versions = ["stable" => "v^", "v#.#"], + versions = ["main" => "main", "stable" => "v^", "v#.#", "dev" => "dev"], ) diff --git a/docs/src/index.md b/docs/src/index.md index e895fed..6b73fc0 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -4,7 +4,7 @@ CurrentModule = SoleViz # SoleViz -Documentation for [SoleViz](https://github.com/aclai-lab/SoleViz.jl). +Welcome to the documentation for [SoleViz](https://github.com/aclai-lab/SoleViz.jl). ```@index ``` diff --git a/src/SoleViz.jl b/src/SoleViz.jl index 7f52f36..4a16219 100644 --- a/src/SoleViz.jl +++ b/src/SoleViz.jl @@ -2,7 +2,7 @@ module SoleViz using Reexport using SoleBase -using SoleData +using MultiData using Statistics using DataFrames using DataStructures diff --git a/src/dataset/descriptors.jl b/src/dataset/descriptors.jl index ef1228c..3283886 100644 --- a/src/dataset/descriptors.jl +++ b/src/dataset/descriptors.jl @@ -5,18 +5,18 @@ TODO: docs # TODOs - Support more than one descriptor in `descriptors` - Support more than one function in `functions` -- Support `attribute_order` to order attributes in plots +- Support `variable_order` to order variables in plots - Implement `plot_dimension` support 3D visualizations for windows - Add more user-friendly interface for `windows` parameter """ function plotdescription( - mfd::AbstractMultiFrameDataset; + md::AbstractMultiDataset; group_descriptors::Union{ # TODO: this should be a Dict{framedimension,itself} <:AbstractVector{Symbol}, <:AbstractDict{<:AbstractString,<:AbstractVector{Symbol}} }, windows::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}} = - [[[(t,0,0) for i in 1:d] for d in dimension(mfd)] for t in [1,2,4,8]], + [[[(t,0,0) for i in 1:d] for d in dimensionality(md)] for t in [1,2,4,8]], cache_descriptions::Union{<:AbstractString,Nothing} = nothing, kwargs... ) @@ -31,13 +31,13 @@ function plotdescription( Threads.@threads for (i, curr_windows) in collect(enumerate(windows)) descriptions[i] = if !isnothing(cache_descriptions) - @scachefast "description" cache_descriptions SoleData.describe( - mfd, + @scachefast "description" cache_descriptions MultiData.describe( + md, desc = desc, t = curr_windows ) else - SoleData.describe(mfd, desc = desc, t = curr_windows) + MultiData.describe(md, desc = desc, t = curr_windows) end end @@ -60,7 +60,7 @@ function plotdescription( kwargs... ) if isnothing(group_descriptors) - group_descriptors = _attributes(descriptions) + group_descriptors = _variables(descriptions) end windows = _get_win(descriptions) @@ -73,9 +73,9 @@ function plotdescription( # TODO: add this to support different # all_descriptors = Vector{Vector{Symbol}}(undef, _ndescriptions(descriptions)) # for i_desc in 1:_descriptions(descriptions) - # all_descriptors[i_desc] = Vector{Symbol}(undef, _nframes(descriptions)) - # for i_frame 1:_nframes(descriptions[i_desc]) - # all_descriptors[i_desc][i_frame] = _descriptors2grouped(group_descriptors) + # all_descriptors[i_desc] = Vector{Symbol}(undef, _nmodalities(descriptions)) + # for i_modality 1:_nmodalities(descriptions[i_desc]) + # all_descriptors[i_desc][i_modality] = _descriptors2grouped(group_descriptors) # end # end singleton_groups = group_descriptors isa AbstractVector @@ -97,22 +97,22 @@ function plotdescription( first_col_name = Symbol(names(curr_description[1])[1]) # get only `descriptor` for each frame of the current description - mono_descriptor_multi_frame_desc = [ + mono_descriptor_multi_modality_desc = [ curr_description[i][:, [first_col_name, descriptor]] - for i in 1:_nframes(curr_description)] + for i in 1:_nmodalities(curr_description)] # for the current descriptor get the stats for all descriptions, frame by frame d = if !isnothing(cache_stats) - [(@scachefast "description" cache_stats SoleData._stat_description( - mono_desc_i_frame; + [(@scachefast "description" cache_stats MultiData._stat_description( + mono_desc_i_modality; functions = functions, - )) for mono_desc_i_frame in mono_descriptor_multi_frame_desc] + )) for mono_desc_i_modality in mono_descriptor_multi_modality_desc] else - [(SoleData._stat_description( - mono_desc_i_frame; + [(MultiData._stat_description( + mono_desc_i_modality; functions = functions, - )) for mono_desc_i_frame in mono_descriptor_multi_frame_desc] + )) for mono_desc_i_modality in mono_descriptor_multi_modality_desc] end push!(_stats, d) @@ -126,10 +126,10 @@ function plotdescription( descriptors = group_descriptors, functions = functions, windows = windows, - # NOTE: number of attributes does not change across different descriptions - n_attributes_per_frame = _nattributes(descriptions)[1], - # NOTE: number of dimensional frames does not change across different descriptions - num_dimensional_frame = _nframes(descriptions)[1], + # NOTE: number of variables does not change across different descriptions + n_variables_per_frame = _nvariables(descriptions)[1], + # NOTE: number of dimensional modalities does not change across different descriptions + num_dimensional_frame = _nmodalities(descriptions)[1], kwargs... ) end @@ -139,34 +139,34 @@ function _plotdescription( descriptors::Union{<:AbstractVector{Symbol},<:AbstractDict{<:AbstractString,<:AbstractVector{Symbol}}}, functions::AbstractVector{Function} = Function[var], plot_kwargs::NamedTuple = NamedTuple(), - attribute_order::Symbol = :keep, # :increasing, :decreasing # TODO + variable_order::Symbol = :keep, # :increasing, :decreasing # TODO layout::Symbol = :triangle, # :rectangle :pyramid plot_dimension::Symbol = :twoD, # :threeD # TODO windows::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}}, - on_x_axis::Symbol = :attributes, # : - attribute_names::Union{<:AbstractVector{<:AbstractString},Nothing} = nothing, + on_x_axis::Symbol = :variables, # : + variable_names::Union{<:AbstractVector{<:AbstractString},Nothing} = nothing, join_plots::Bool = false, - n_attributes_per_frame::AbstractVector{<:Integer}, + n_variables_per_frame::AbstractVector{<:Integer}, num_dimensional_frame::Integer ) @assert windows == [[[(1,0,0)]]] "$(windows)" @assert length(functions) == 1 - @assert on_x_axis in [:descriptors, :attributes] + @assert on_x_axis in [:descriptors, :variables] allowed_plot_dimensionts = [:twoD, :threeD] @assert plot_dimension in allowed_plot_dimensionts "Value `$(plot_dimension)` not " * "allowed: available are $(allowed_plot_dimensionts)" - allowed_attribute_order = [:keep, :increasing, :decreasing] - @assert attribute_order in allowed_attribute_order "Value `$(attribute_order)` not " * - "allowed: available are $(allowed_attribute_order)" + allowed_variable_order = [:keep, :increasing, :decreasing] + @assert variable_order in allowed_variable_order "Value `$(variable_order)` not " * + "allowed: available are $(allowed_variable_order)" allowed_layout = [:triangle, :rectangle, :pyramid] @assert layout in allowed_layout "Value `$(layout)` not " * "allowed: available are $(allowed_layout)" - # concat symbols + # concatenate symbols cs(s1::Symbol, s2::Symbol) = Symbol(string(s1, "_", s2)) # blank plots bp() = plot() # plot(; ticks = false, grid = true, axis = true) @@ -181,42 +181,42 @@ function _plotdescription( )]) - max_n_attributes = (n_attributes_per_frame)|>maximum + max_n_variables = (n_variables_per_frame)|>maximum if join_plots mega_plot = bp() else - plot_pyramids = Array{Plots.Plot}(undef, length(windows), pyramid_base_length, (on_x_axis == :attributes ? length(descriptors) : max_n_attributes), num_dimensional_frame) + plot_pyramids = Array{Plots.Plot}(undef, length(windows), pyramid_base_length, (on_x_axis == :variables ? length(descriptors) : max_n_variables), num_dimensional_frame) for i in 1:length(plot_pyramids) plot_pyramids[i] = bp() end end # For each frame - for (i_frame, dim) in enumerate(num_dimensional_frame) + for (i_modality, dim) in enumerate(num_dimensional_frame) if dim isa Symbol - # throw(ErrorException("`plotdescription` still not implemented for `$(dim)` frames")) + # throw(ErrorException("`plotdescription` still not implemented for `$(dim)` modalities")) continue elseif dim == 0 - # throw(ErrorException("`plotdescription` still not implemented for static frames")) + # throw(ErrorException("`plotdescription` still not implemented for static modalities")) continue end for (i_win, win) in enumerate(windows) - curr_frame_window = win[i_frame] + curr_frame_window = win[i_modality] - if on_x_axis == :attributes + if on_x_axis == :variables # For each descriptor for (i_descriptor_group,(descriptor_group_name,descrs)) in enumerate(descriptors) for (i_descriptor,descriptor) in enumerate(descrs) - d = stats[i_descriptor_group][i_descriptor][i_win][i_frame]; + d = stats[i_descriptor_group][i_descriptor][i_win][i_modality]; names = d[:,1] - n_attributes = nrow(d) + n_variables = nrow(d) col = cs(descriptor, nameof(functions[1])) - x = collect(1:n_attributes) + x = collect(1:n_variables) ys = d[:,col] for i_chunk in 1:pyramid_base_length @@ -236,24 +236,24 @@ function _plotdescription( end elseif on_x_axis == :descriptors - ds = [(stats[i_descriptor_group][i_descriptor][i_win][i_frame], descriptor) for (i_descriptor_group,(descriptor_group_name,descrs)) in enumerate(descriptors) for (i_descriptor,descriptor) in enumerate(descrs)]; + ds = [(stats[i_descriptor_group][i_descriptor][i_win][i_modality], descriptor) for (i_descriptor_group,(descriptor_group_name,descrs)) in enumerate(descriptors) for (i_descriptor,descriptor) in enumerate(descrs)]; n_descriptors = length(ds) # println(ds) - # For each attribute - for i_attribute in 1:n_attributes_per_frame[i_frame] + # For each variable + for i_variable in 1:n_variables_per_frame[i_modality] x = collect(1:n_descriptors) - ys = [d[i_attribute, cs(descriptor, nameof(functions[1]))] for (d,descriptor) in ds] + ys = [d[i_variable, cs(descriptor, nameof(functions[1]))] for (d,descriptor) in ds] names = [cs(descriptor, nameof(functions[1])) for (d,descriptor) in ds] # println(ys) for i_chunk in 1:pyramid_base_length - attribute_name = isnothing(attribute_names) ? "$(VARPREFIX)$(i_attribute)" : attribute_names[i_attribute] - plot!((join_plots ? mega_plot : plot_pyramids[i_win, i_chunk, i_attribute, num_dimensional_frame]), + variable_name = isnothing(variable_names) ? "$(VARPREFIX)$(i_variable)" : variable_names[i_variable] + plot!((join_plots ? mega_plot : plot_pyramids[i_win, i_chunk, i_variable, num_dimensional_frame]), x, # TODO: generalize on n-th function in functions [v[i_chunk] for v in ys], - labels = string("$(attribute_name)"), - title = (join_plots ? "" : "$(attribute_name)$(pyramid_base_length == 1 ? "" : " $(i_chunk) / $(curr_frame_window[1][1])")"), + labels = string("$(variable_name)"), + title = (join_plots ? "" : "$(variable_name)$(pyramid_base_length == 1 ? "" : " $(i_chunk) / $(curr_frame_window[1][1])")"), xticks = (1:length(x), string.(names)), xrotation = 65, xtickfontrotation = 65, diff --git a/src/dataset/utils.jl b/src/dataset/utils.jl index 86fb4e2..69916a5 100644 --- a/src/dataset/utils.jl +++ b/src/dataset/utils.jl @@ -66,15 +66,15 @@ function _framedims(d::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple end """ - _nframes(d) + _nmodalities(d) -Get the number of frames in `d`. +Get the number of modalities in `d`. """ -function _nframes(d::AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}) +function _nmodalities(d::AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}) return length(d) end -function _nframes(d::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}}) - return [_nframes(w) for w in d] +function _nmodalities(d::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple{3,<:Integer}}}}) + return [_nmodalities(w) for w in d] end """ @@ -125,7 +125,7 @@ function _get_r(d::AbstractVector{<:AbstractVector{<:AbstractVector{<:NTuple{3,< return [_get_r(w) for w in d] end -## MFD description object +## MD description object # Vector{Vector{DataFrame}} function _is_description(dfs::AbstractDataFrame) @@ -153,9 +153,9 @@ function _framedims(d::AbstractVector{<:AbstractArray}) return length(d) > 0 ? _framedims(d[1]) : [] end function _framedims(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" + @assert _is_description(d) "`d` has to be a MultiDataset description" - # NOTE: assumed all attributes have same dimension + # NOTE: assumed all variables have same dimension return _framedims(d[1,2]) end function _framedims(d::AbstractVector{<:AbstractDataFrame}) @@ -165,13 +165,13 @@ function _framedims(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) return [_framedims(w) for w in d] end -function _nframes(d::AbstractVector{<:AbstractDataFrame}) +function _nmodalities(d::AbstractVector{<:AbstractDataFrame}) return length(d) end -function _nframes(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) - return [_nframes(w) for w in d] +function _nmodalities(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) + return [_nmodalities(w) for w in d] end -function _nframes(d::AbstractDataFrame) +function _nmodalities(d::AbstractDataFrame) return 1 end @@ -184,9 +184,9 @@ function _get_win(d::AbstractVector{<:AbstractArray}) return length(d) > 0 ? _get_win(d[1]) : [] end function _get_win(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" + @assert _is_description(d) "`d` has to be a MultiDataset description" - # NOTE: assumed all attributes have same dimension + # NOTE: assumed all variables have same dimension return _get_win(d[1,2]) end function _get_win(d::AbstractVector{<:AbstractDataFrame}) @@ -196,32 +196,32 @@ function _get_win(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) return [_get_win(w) for w in d] end -function _nattributes(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" +function _nvariables(d::AbstractDataFrame) + @assert _is_description(d) "`d` has to be a MultiDataset description" return nrow(d) end -function _nattributes(d::AbstractVector{<:AbstractDataFrame}) - return [_nattributes(frame) for frame in d] +function _nvariables(d::AbstractVector{<:AbstractDataFrame}) + return [_nvariables(frame) for frame in d] end -function _nattributes(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) - return [_nattributes(description) for description in d] +function _nvariables(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) + return [_nvariables(description) for description in d] end -function _attributes(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" +function _variables(d::AbstractDataFrame) + @assert _is_description(d) "`d` has to be a MultiDataset description" return Symbol.(d[:,1]) end -function _attributes(d::AbstractVector{<:AbstractDataFrame}) - return [_attributes(frame) for frame in d] +function _variables(d::AbstractVector{<:AbstractDataFrame}) + return [_variables(frame) for frame in d] end -function _attributes(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) - return [_attributes(description) for description in d] +function _variables(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) + return [_variables(description) for description in d] end function _ndescriptors(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" + @assert _is_description(d) "`d` has to be a MultiDataset description" return ncol(d) - 1 end @@ -233,7 +233,7 @@ function _ndescriptors(d::AbstractVector{<:AbstractVector{<:AbstractDataFrame}}) end function _descriptors(d::AbstractDataFrame) - @assert _is_description(d) "`d` has to be a MultiFrameDataset description" + @assert _is_description(d) "`d` has to be a MultiDataset description" return Symbol.(names(d)[2:end]) end