Utilities

SomeGraphs.Utilities Module

Utility functions for defining graph types. We do not re-export all symbols from this sub-module to the global MCGraphs namespace. You can safely ignore these unless you are implementing a new graph type.

SomeGraphs.Validations.Maybe Type
Maybe{T} = Union{T, Nothing}

The type to use when maybe there is a value, maybe there isn't. This is exactly as if writing the explicit Union with Nothing but is shorter and more readable. This is extremely common.

Note

This is replicated from TanayLabUtilities to avoid making it a dependency. We do not export it but use it extensively in the type signatures.

SomeGraphs.Common.validate_graph Function
validate_graph(::Graph)::Maybe{AbstractString}

Validate that the combination of data and configuration in a graph is valid, after validating each one separately. This isn't invoked manually, instead it is called by the overall validate of the graph. It is provided (with a default empty implementation) to allow for type-specific validations.

SomeGraphs.Common.graph_to_figure Function
graph_to_figure(graph::Graph)::PlotlyFigure

Render a graph given its data and configuration. Technically this just converts the graph to a PlotlyFigure which Julia knows how display for us, rather than actually display the graph. The implementation depends on the specific graph type.

You can just write graph.figure instead of graph_to_figure(graph) .

Note

When saving a figure to a file, Plotly in its infinite wisdom ignores the graph width and height specified inside the figure, (except for saving HTML file). You should therefore use save_graph rather than call savefig on the result of graph_to_figure .

SomeGraphs.Utilities.plotly_figure Function
plotly_figure(trace::GenericTrace, layout::Layout)::PlotlyFigure
plotly_figure(traces::AbstractVector{<:GenericTrace}, layout::Layout)::PlotlyFigure

Wrap a trace or a set of traces with the accompanying layout in a PlotlyFigure .

SomeGraphs.Utilities.validate_colors Function
validate_colors(
    colors_data_context::ValidationContext,
    colors_data::Maybe{Union{AbstractVector{<:AbstractString}, AbstractVector{<:Real}}},
    colors_configuration_context::ValidationContext,
    colors_configuration::ColorsConfiguration,
    mask::Maybe{Union{AbstractVector{Bool},BitVector}} = nothing,
)::Nothing
validate_colors(
    colors_data_context::ValidationContext,
    colors_data::AbstractMatrix{<:Real},
    colors_configuration_context::ValidationContext,
    colors_configuration::ColorsConfiguration,
    mask::Maybe{Union{AbstractVector{Bool},BitVector}} = nothing,
)::Nothing

Validate that the colors_data from the colors_data_context is valid and consistent with the colors_configuration from the colors_configuration_context . For example, if the color configuration contains a categorical color mapping, this will validate that all the color names in the data are valid keys of this mapping.

If a mask is specified, do not validate colors in the data whose matching value in the mask is false.

SomeGraphs.Utilities.fill_color Function
fill_color(line_color::Maybe{AbstractString})::Maybe{AbstractString}

Return a fill color based on a line_color . The fill color is twice as transparent as the line color.

SomeGraphs.Utilities.ConfiguredColors Type
@kwdef mutable struct ConfiguredColors
    colors_title::Maybe{AbstractString}
    colors_configuration::ColorsConfiguration
    colors_scale_index::Maybe{Integer}
    original_color_values::Maybe{Union{AbstractVector{<:AbstractString}, AbstractVector{<:Real}}}
    final_colors_values::Maybe{Union{AbstractVector{<:AbstractString}, AbstractVector{<:Real}}}
    final_colors_range::Maybe{Range}
    scaled_colors_palette::Maybe{AbstractVector{<:Tuple{Real, AbstractString}}}
    show_in_legend::Bool
    show_scale::Bool
end

Colors data after applying the configuration.

SomeGraphs.Utilities.configured_colors Function
configured_colors(;
    colors_configuration::ColorsConfiguration,
    colors_title::Maybe{AbstractString},
    colors_values::Maybe{Union{AbstractVector{<:Real}, AbstractVector{<:AbstractString}, AbstractMatrix{<:Real}}},
    next_colors_scale_index::AbstractVector{<:Integer},
    mask::Maybe{Union{AbstractVector{Bool}, BitVector}} = nothing,
)::ConfiguredColors

Apply the colors configuration to the colors data.

SomeGraphs.Utilities.validate_axis_sizes Function
validate_axis_sizes(;
    axis_name::AbstractString,
    graphs_gap::Maybe{Real} = nothing,
    n_graphs::Integer = 1,
    annotation_size::AnnotationSize,
    n_annotations::Integer,
    dendogram_size::Maybe{Real} = nothing,
)::nothing

Verify there is at least some space left for the actual graph after leaving space for gaps and/or annotations.

SomeGraphs.Utilities.validate_values Function
validate_values(
    values_data_context::ValidationContext,
    values_data::Maybe{AbstractVector{<:Real}}},
    axis_configuration_context::ValidationContext,
    axis_configuration::AxisConfiguration,
)::Nothing

Validate that the values_data from the values_data_context is valid and consistent with the axis_configuration from the axis_configuration_context . Specifically this ensures that if a log_scale is applied, all the values are positive.

SomeGraphs.Utilities.scale_axis_value Function
scale_axis_value(axis_configuration::AxisConfiguration, value::Real; clamp::Bool = true)::Real
scale_axis_value(axis_configuration::AxisConfiguration, value::Nothing; clamp::Bool = true)::Nothing

Scale a single value according to the axis_configuration . This deals with log scales and percent scaling. By default, clamp the values to a specified explicit range.

SomeGraphs.Utilities.scale_axis_values Function
scale_axis_values(
    axis_configuration::AxisConfiguration,
    values::Maybe{AbstractVector{<:Maybe{Real}}};
    clamp::Bool = true
)::Maybe{AbstractVector{<:Maybe{AbstractFloat}}}
scale_axis_values(
    axis_configuration::AxisConfiguration,
    values::Maybe{AbstractMatrix{<:Maybe{Real}}};
    clamp::Bool = true
)::Maybe{AbstractMatrix{<:Maybe{AbstractFloat}}}

Scale a vector of values according to the axis_configuration . This deals with log scales and percent scaling. By default, clamp the values to a specified explicit range. If copy we always return a copy of the data (so it can be safely modified further without impacting the original data).

SomeGraphs.Utilities.scale_size_values Function
scale_size_values(
    sizes_configuration::SizesConfiguration,
    values::Maybe{AbstractVector{<:Real}},
)::Maybe{AbstractVector{<:Real}}

Scale a vector of values according to sizes_configuration .

SomeGraphs.Utilities.plotly_layout Function
plotly_layout(
    figure_configuration::FigureConfiguration;
    title::Maybe{AbstractString},
    has_legend::Bool,
    shapes::AbstractVector{Shape},
)::Layout

Create a Plotly Layout object.

SomeGraphs.Utilities.set_layout_axis! Function
set_layout_axis!(
    layout::Layout,
    axis::AbstractString
    axis_configuration::AxisConfiguration;
    title::Maybe{AbstractString},
    range::Range,
    domain::Maybe{AbstractVector{<:Real}} = nothing,
)::Nothing

Add a Plotly axis in a layout using the axis_configuration .

SomeGraphs.Utilities.set_layout_colorscale! Function
set_layout_colorscale!(;
    layout::Layout,
    colors_scale_index::Integer,
    colors_configuration::ColorsConfiguration,
    scaled_colors_palette::Maybe{AbstractVector{<:Tuple{Real, AbstractString}}},
    offset::Maybe{Real},
    range::Maybe{Range} = nothing,
    title::Maybe{AbstractString},
    show_scale::Bool,
)::Nothing

Set a colorscale in a Plotly layout , as specified by a colors_configuration . Since Plotly is dumb when it comes to placement of color scales, the offset must be specified manually to avoid overlaps.

SomeGraphs.Utilities.SubGraph Type
@kwdef struct SubGraph
    index::Integer
    n_graphs::Integer
    gap::Maybe{AbstractFloat}
    n_annotations::Integer = 0
    annotation_size::Maybe{AnnotationSize} = nothing
    dendogram_size::Maybe{Real} = nothing
end

Identify one sub-graph out of a set of n_graphs adjacent graphs along some axis. If the index is 1, this is the 1st sub-graph (used top initialize some values such as the legend group title). If gap is nothing then the sub-graphs are plotted on top of each other, which affects axis parameters; otherwise, the sub-graphs are plotted with this gap, which affects layout parameters.

This also supports n_annotations (of the other axis) with annotation_size (along this axis). If the index is negative, it is the (negated) index of an annotation (of the other axis).

If the index is 0, this is the dendogram graph (of the other axis) with dendogram_size (along this axis).

SomeGraphs.Utilities.plotly_sub_graph_axes Function
plotly_sub_graph_axes(;
    basis_sub_graph::Maybe{SubGraph} = nothing,
    values_sub_graph::Maybe{SubGraph} = nothing,
    values_orientation::ValuesOrientation,
)::Tuple{
    Maybe{Integer},
    Maybe{AbstractFloat},
    Maybe{Integer},
    Maybe{AbstractFloat},
}

Return the X axis index and zero value, and the Y axis index and zero value, for a sub-graph.

SomeGraphs.Utilities.plotly_axis Function
plotly_axis(prefix::AbstractString, index::Maybe{Integer}; short::Bool = false, force::Bool = false)::Maybe{AbstractString}

Return the Plotly axis name for a given index. If short just use the prefix , otherwise add axis . If force give a result even for the 1st (typically implicit, unnamed) axis.

SomeGraphs.Utilities.validate_graph_bands Function
validate_graph_bands(
    field::AbstractString,
    bands_configuration::BandsConfiguration,
    bands_data::BandsData,
    axis_configuration::Maybe{AxisConfiguration} = nothing,
)::Nothing

Validate that the bands configuration and data is compatible. Assumes these are specified as the same field in both the graph's data and configuration.

SomeGraphs.Utilities.push_horizontal_bands_shapes Function
push_horizontal_bands_shapes(
    shapes::AbstractVector{Shape},
    axis_configuration::AxisConfiguration,
    scaled_values_range::Range,
    bands_data::BandsData,
    bands_configuration::BandsConfiguration,
    bands_scale::Real = 1,
)::AbstractVector{<:Shape}

Push shapes for plotting horizontal bands. These shapes need to be placed in the layout and not the traces because Plotly.

SomeGraphs.Utilities.push_vertical_bands_shapes Function
push_vertical_bands_shapes(
    shapes::AbstractVector{Shape},
    axis_configuration::AxisConfiguration,
    scaled_values_range::Range,
    bands_data::BandsData,
    bands_configuration::BandsConfiguration,
    bands_scale::Real = 1,
)::AbstractVector{<:Shape}

Push shapes for plotting vertical bands. These shapes need to be places in the layout and not the traces because Plotly.

SomeGraphs.Utilities.push_diagonal_bands_shapes Function
push_diagonal_bands_shapes(
    shapes::AbstractVector{Shape},
    x_axis_configuration::AxisConfiguration,
    y_axis_configuration::AxisConfiguration,
    x_scaled_values_range::Range,
    y_scaled_values_range::Range,
    bands_data::BandsData,
    bands_configuration::BandsConfiguration
)::AbstractVector{<:Shape}

Push shapes for plotting diagonal bands. These shapes need to be placed in the layout and not the traces because Plotly.

SomeGraphs.Utilities.MaybeRange Type
@kwdef mutable struct MaybeRange
    minimum::Maybe{Float32} = nothing
    maximum::Maybe{Float32} = nothing
end

A range of values (possibly partially specified).

SomeGraphs.Utilities.final_scaled_range Function
final_scaled_range(
    implicit_scaled_range::Union{Range, MaybeRange},
    axis_configuration::AxisConfiguration
)::Range,

Compute the final range for some axis given the implicit_scaled_range computed from the values and the axis_configuration .

SomeGraphs.Utilities.prefer_data Function
prefer_data(data_value::Any, configuration_value::Any)::Any
prefer_data(data_values::AbstractVector, index::Integer, configuration_value::Any)::Any

Return a value to use, prefering the data value (which may be in a vector) to the configuration value.

Index