-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Apply the transform_func on positions, to work in nonlinear scale (#14)
* Apply the transform_func as well in order to work in nonlinear scale * Fix typos * Transform back until we have `space == :transformed` * Add an example of the Julia microbenchmarks in beeswarm * scale -> scales.md * dict not dataframe in example * Finally fix example * Even more unconventional example * fix Octave * Fix color type * Better file structure for examples * clean up * Do not edit marker position if group is empty This fixes issues encountered when using missing or NaN data.
- Loading branch information
1 parent
d4c1056
commit a0e233b
Showing
8 changed files
with
240 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,4 @@ | |
*/node_modules/* | ||
.DS_Store | ||
|
||
docs/src/examples.md | ||
docs/src/examples/examples.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
[deps] | ||
AlgebraOfGraphics = "cbdf2221-f076-402e-a563-3d30da359d67" | ||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" | ||
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" | ||
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" | ||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" | ||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" | ||
DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365" | ||
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" | ||
PalmerPenguins = "8b842266-38fa-440a-9b57-31493939ab85" | ||
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" | ||
Rsvg = "c4c386cf-5103-5370-be45-f3a111cca3b8" | ||
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" | ||
SwarmMakie = "0b1c068e-6a84-4e66-8136-5c95cafa83ed" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Scaled beeswarm plots | ||
|
||
Beeswarm plots can also be plotted in log-scale axes! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
# Unconventional swarm plots | ||
|
||
You can use swarm plots to simply separate scatter markers which share the same `x` coordinate, and distinguish them by color and marker type. | ||
|
||
|
||
## The Julia benchmark plot | ||
|
||
```@example julia-benchmark | ||
# Load the required Julia packages | ||
using Base.MathConstants | ||
using CSV | ||
using DataFrames | ||
using AlgebraOfGraphics, SwarmMakie, CairoMakie | ||
using StatsBase, CategoricalArrays | ||
# Load benchmark data from file | ||
benchmarks = | ||
CSV.read(download("https://raw.githubusercontent.com/JuliaLang/Microbenchmarks/master/bin/benchmarks.csv"), DataFrame; header = ["language", "benchmark", "time"]) | ||
# Capitalize and decorate language names from datafile | ||
dict = Dict( | ||
"c" => "C", | ||
"julia" => "Julia", | ||
"lua" => "LuaJIT", | ||
"fortran" => "Fortran", | ||
"java" => "Java", | ||
"javascript" => "JavaScript", | ||
"matlab" => "Matlab", | ||
"mathematica" => "Mathematica", | ||
"python" => "Python", | ||
"octave" => "Octave", | ||
"r" => "R", | ||
"rust" => "Rust", | ||
"go" => "Go", | ||
); | ||
benchmarks[!, :language] = [dict[lang] for lang in benchmarks[!, :language]] | ||
# Normalize benchmark times by C times | ||
ctime = benchmarks[benchmarks[!, :language] .== "C", :] | ||
benchmarks = innerjoin(benchmarks, ctime, on = :benchmark, makeunique = true) | ||
select!(benchmarks, Not(:language_1)) | ||
rename!(benchmarks, :time_1 => :ctime) | ||
benchmarks[!, :normtime] = benchmarks[!, :time] ./ benchmarks[!, :ctime]; | ||
# Compute the geometric mean for each language | ||
langs = []; | ||
means = []; | ||
priorities = []; | ||
for lang in benchmarks[!, :language] | ||
data = benchmarks[benchmarks[!, :language] .== lang, :] | ||
gmean = geomean(data[!, :normtime]) | ||
push!(langs, lang) | ||
push!(means, gmean) | ||
if (lang == "C") | ||
push!(priorities, 1) | ||
elseif (lang == "Julia") | ||
push!(priorities, 2) | ||
else | ||
push!(priorities, 3) | ||
end | ||
end | ||
# Add the geometric means back into the benchmarks dataframe | ||
langmean = Dict(langs .=> tuple.(means, priorities)) | ||
benchmarks.geomean = first.(getindex.((langmean,), benchmarks.language)) | ||
benchmarks.priority = last.(getindex.((langmean,), benchmarks.language)) | ||
# Put C first, Julia second, and sort the rest by geometric mean | ||
sort!(benchmarks, [:priority, :geomean]); | ||
langs = CategoricalArray(benchmarks.language) | ||
bms = CategoricalArray(benchmarks.benchmark) | ||
f, a, p = beeswarm( | ||
langs.refs, benchmarks.normtime; | ||
color = bms.refs, | ||
colormap = :Set2_8, | ||
# markersize = 5, | ||
marker = Circle, | ||
axis = (; | ||
yscale = log10, | ||
xticklabelrotation = 0, | ||
xticklabelsize = 12, | ||
xticksvisible = false, | ||
topspinecolor = :gray, | ||
bottomspinecolor = :gray, | ||
leftspinecolor = :gray, | ||
rightspinecolor = :gray, | ||
ylabel = "Time relative to C", | ||
xticks = (1:length(unique(langs)), langs.pool.levels), | ||
xminorticks = IntervalsBetween(2), | ||
xgridvisible = false, | ||
xminorgridvisible = true, | ||
xminorgridcolor = (:black, 0.2), | ||
yminorticks = IntervalsBetween(5), | ||
yminorgridvisible = true, | ||
), | ||
figure = (; size = (1000, 618),) | ||
) | ||
leg = Legend(f[1, 2], | ||
[MarkerElement(; color = Makie.categorical_colors(:Set1_8, 8)[i], marker = :circle, markersize = 11) for i in 1:length(bms.pool.levels)], | ||
bms.pool.levels, | ||
"Benchmark"; | ||
) | ||
f | ||
``` | ||
|
||
|
||
## Benchmarks colored by language | ||
|
||
```@example julia-benchmark | ||
f, a, p = beeswarm( | ||
bms.refs, benchmarks.normtime; | ||
color = langs.refs, | ||
colormap = Makie.Colors.distinguishable_colors(13),#:Set1_9, | ||
# markersize = 5, | ||
marker = Circle, | ||
axis = (; | ||
yscale = log10, | ||
xticklabelrotation = 0, | ||
xticklabelsize = 12, | ||
xticksvisible = false, | ||
topspinecolor = :gray, | ||
bottomspinecolor = :gray, | ||
leftspinecolor = :gray, | ||
rightspinecolor = :gray, | ||
ylabel = "Time relative to C", | ||
xticks = (1:length(unique(bms)), bms.pool.levels), | ||
xminorticks = IntervalsBetween(2), | ||
xgridvisible = false, | ||
xminorgridvisible = true, | ||
xminorgridcolor = (:black, 0.2), | ||
yminorticks = IntervalsBetween(5), | ||
yminorgridvisible = true, | ||
), | ||
figure = (; size = (1000, 618),) | ||
) | ||
leg = Legend(f[1, 2], | ||
[MarkerElement(; color = p.colormap[][i], marker = :circle, markersize = 11) for i in 1:length(langs.pool.levels)], | ||
langs.pool.levels, | ||
"Benchmark"; | ||
) | ||
f | ||
``` | ||
|
||
## Custom markers | ||
```@example julia-benchmark | ||
# Get logos for programming languages | ||
using Rsvg | ||
using CairoMakie | ||
using CairoMakie.Cairo, CairoMakie.FileIO | ||
function pngify(input_data::AbstractString) | ||
r = Rsvg.handle_new_from_data(String(input_data)); | ||
Rsvg.handle_set_dpi(r, 2.0) | ||
d = Rsvg.handle_get_dimensions(r); | ||
img = fill(Makie.Colors.ARGB32(0, 0, 0, 0), d.width * 4, d.height * 4) | ||
# create an image surface to draw onto the image | ||
surf = Cairo.CairoImageSurface(img) | ||
ctx = Cairo.CairoContext(surf); | ||
Cairo.scale(ctx, 4, 4) | ||
Rsvg.handle_render_cairo(ctx,r); | ||
return permutedims(img) | ||
end | ||
language_logo_url(lang::String) = "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/$(lowercase(lang))/$(lowercase(lang))-original.svg" | ||
language_marker_dict = Dict( | ||
[key => read(download(language_logo_url(key)), String) |> pngify for key in ("c", "fortran", "go", "java", "javascript", "julia", "matlab", "python", "r", "rust")] | ||
) | ||
language_marker_dict["octave"] = FileIO.load(File{format"PNG"}(download("https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Gnu-octave-logo.svg/2048px-Gnu-octave-logo.svg.png"))) .|> Makie.Colors.ARGB32 | ||
language_marker_dict["luajit"] = read(download(language_logo_url("lua")), String) |> pngify | ||
language_marker_dict["mathematica"] = read(download("https://upload.wikimedia.org/wikipedia/commons/2/20/Mathematica_Logo.svg"), String) |> pngify | ||
f, a, p = beeswarm( | ||
bms.refs, benchmarks.normtime; | ||
marker = getindex.((language_marker_dict,),lowercase.(benchmarks.language)), | ||
markersize = 11, | ||
axis = (; | ||
yscale = log10, | ||
xticklabelrotation = 0, | ||
xticklabelsize = 12, | ||
xticksvisible = false, | ||
topspinecolor = :gray, | ||
bottomspinecolor = :gray, | ||
leftspinecolor = :gray, | ||
rightspinecolor = :gray, | ||
ylabel = "Time relative to C", | ||
xticks = (1:length(unique(bms)), bms.pool.levels), | ||
xminorticks = IntervalsBetween(2), | ||
xgridvisible = false, | ||
xminorgridvisible = true, | ||
xminorgridcolor = (:black, 0.2), | ||
yminorticks = IntervalsBetween(5), | ||
yminorgridvisible = true, | ||
), | ||
figure = (; size = (1000, 618),) | ||
) | ||
leg = Legend(f[1, 2], | ||
[MarkerElement(; marker = language_marker_dict[lowercase(lang)], markersize = 15) for lang in langs.pool.levels], | ||
langs.pool.levels, | ||
"Language"; | ||
) | ||
f | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters