Extensions
Extension for Plots
We used the same settings for the plot
function in all previous examples. Therefore, it makes sense to write an auxiliary function setting attributes for the plot
function. However, this function will depend on the Plots
package, and if we add Plots
to ImageInspector
, it will significantly slow the loading time.
To define an extension, we need firstly modify the Project.toml
. We have to add two new sections. The first new section weakdeps
specifies all the dependencies we need for our extension. In our case, we only need Plots
, so we add the following in the Project.toml
[weakdeps]
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
The second new section is extensions
and in this section, we have to specify the extension name and the dependencies that the extension uses. In our case, the name is PlotsExt
and we only need Plots
(more dependencies can be specified as a list of their names)
[extensions]
PlotsExt = "Plots"
We can also specify which versions of Plots
package our extension supports. It can be done by adding a new record in the compat
section
[compat]
Aqua = "0.8"
Colors = "0.12, 0.13"
Plots = "1"
Test = "1.9"
julia = "1.9"
Now, we define an empty function imageplot
inside of the ImageInstructor, i. e., we add the foollowing code to the src/ImageInstructor.jl
# src/ImageInstructor.jl
function imageplot end
This step is needed, since we will add methods to this function inside our extention.
The last step is to create the extension itself. The code for extension must be stored in ext
folder in the root dir of the package. The code for the extension is them must be defined in the file with the same name, i. e., we have to create a new file ext/PlotsExt.jl
and add the code into it
# ext/PlotsExt.jl
module PlotsExt
import Plots
using ImageInspector
using ImageInspector.Colors
function ImageInspector.imageplot(x, ind; flip=true, nrows=-1, ncols=-1, sep=1, kwargs...)
img = imagegrid(x, ind; flip, nrows, ncols, sep)
return imageplot(img; kwargs...)
end
function ImageInspector.imageplot(x; flip=true, kwargs...)
img = image(x; flip)
return imageplot(img; kwargs...)
end
function ImageInspector.imageplot(
x::AbstractMatrix{<:Color};
legend=false,
axis=nothing,
border=:none,
kwargs...
)
return Plots.plot(x; legend, axis, border, kwargs...)
end
end
Note, that we defined a new module, that has the same name as our extension. And that's all. Now we can test, whether the extension works. We have to start a new Julia session and activate examples
enviroment. Now, if we do not load Plots
, the imageplot
function will have no methods, as can be seen below
julia> using ImageInspector, MLDatasets
julia> x = CIFAR10(split=:train).features;
julia> imageplot(x, 1:10; nrows = 2, sep = 1)
ERROR: MethodError: no method matching imageplot(::Array{Float32, 4}, ::UnitRange{Int64}; nrows::Int64, sep::Int64)
[...]
After loading the Plots
package, the imageplot
function will start working.
julia> using Plots
julia> imageplot(x, 1:10; nrows = 2, sep = 1)
Extension for Makie
We can create multiple extensions for one package. For example, we can also create an extension for Makie.jl
, which is an alternative package for generating plots. To do so, we have to follow the same steps as in the case of extension for Plots
.
The first step is to modify the Project.toml
file in the following way
[weakdeps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
[extensions]
MakieExt = "CairoMakie"
PlotsExt = "Plots"
[compat]
Aqua = "0.8"
CairoMakie = "0.12"
Colors = "0.12, 0.13"
Plots = "1"
Test = "1.9"
julia = "1.9"
In other words, our extension for Makie
has name MakieExt
and depends on CairoMakie
. Now we can create the extension itself by creating file ext/MakieExt.jl
and adding the following code into it
module MakieExt
import CairoMakie
using ImageInspector
using ImageInspector.Colors
function ImageInspector.imageplot(x, ind; flip=true, nrows=-1, ncols=-1, sep=1, kwargs...)
img = imagegrid(x, ind; flip, nrows, ncols, sep)
return imageplot(img; kwargs...)
end
function ImageInspector.imageplot(x; flip=true, kwargs...)
img = image(x; flip)
return imageplot(img; kwargs...)
end
function ImageInspector.imageplot(x::AbstractMatrix{<:Color}; kwargs...)
f, ax = CairoMakie.image(reverse(x'; dims=2); kwargs...)
CairoMakie.hidedecorations!(ax)
CairoMakie.hidespines!(ax)
return f
end
end
Now it's time to test the extension. To do so, we first have to install CairoMakie
into examples
enviroment
(ImageInspector) pkg> activate ./examples
(examples) pkg> add CairoMakie
We have to start a new Julia session and activate examples
enviroment. Now, if we do not load CairoMakie
, the imageplot
function will have no methods, as can be seen below
julia> using ImageInspector, MLDatasets
julia> x = CIFAR10(split=:train).features;
julia> imageplot(x, 1:10; nrows = 2, sep = 1)
ERROR: MethodError: no method matching imageplot(::Array{Float32, 4}, ::UnitRange{Int64}; nrows::Int64, sep::Int64)
[...]
After loading the CairoMakie
package, the imageplot
function will start working.
julia> using CairoMakie
julia> imageplot(x, 1:10; nrows = 2, sep = 1)