The logo is composed of three disks build of points (scatter-plot) of three colors: red, green and purple. So let’s start small and try to replicate it by placing the points (only three for now) on a graph in their correct locations.
import CairoMakie as Cmk
function drawLogo()::Cmk.Figure
centersXs::Vec{Flt} = [1, 5.5, 10]
centersYs::Vec{Flt} = [1, 6, 1]
colors::Vec{Str} = ["red", "green", "purple"]
fig::Cmk.Figure = Cmk.Figure()
ax::Cmk.Axis = Cmk.Axis(fig[1, 1])
Cmk.scatter!(ax, centersXs, centersYs, color=colors, markersize=50)
return fig
end
Note:
CairoMakie
usesColors.jl
, the list of available color names is to be found here.
The function is pretty simple. First, we defined the locations (based on guess and later try and error) of the points with respect to the x- (centersXs
) and y-axis (centersYs
), as well as their colors. Next we added the points (scatter!
) to the axis object (ax
) attached to the figure object (fig
).
Time to take a look.
drawLogo()
So far, so good. Now instead of a one big point we will need a few thousand smaller points (let’s say markersize=10
) concentrated around the center of a given group. Moreover, the points should be partially transparent [to that end we will use alpha
keyword argument (alpha=0
- fully transparent, alpha=1
- fully opaque)]. One more thing, the points need to be randomly scattered, but with a greater density closer to the group’s center. This last issue will be solved by obtaining random numbers from the normal distribution with the mean equal 0 and the standard deviation equal 1. This is what randn
function will do. Thanks to this roughly 68% of the numbers will be in the range -1 to 1, 95% in the range -2 to 2, and 99.7% in the range -3 to 3 (greater density around the mean). Behold.
import Random as Rnd
function drawLogo()::Cmk.Figure
centersXs::Vec{Flt} = [1, 5.5, 10]
centersYs::Vec{Flt} = [1, 6, 1]
colors::Vec{Str} = ["red", "green", "purple"]
numOfPoints::Int = 3000
fig::Cmk.Figure = Cmk.Figure()
ax::Cmk.Axis = Cmk.Axis(fig[1, 1])
for i in eachindex(colors)
Cmk.scatter!(ax,
centersXs[i] .+ Rnd.randn(numOfPoints),
centersYs[i] .+ Rnd.randn(numOfPoints),
color=colors[i], markersize=10, alpha=0.25)
end
return fig
end
Let’s test it.
Rnd.seed!(303) # needed to make it reproducible
drawLogo()
We’re almost there. Notice, that CairoMakie
nicely centered the plot, so we don’t need to do this ourselves manually.
Anyway, all that’s left to do is to remove the unnecessary elements from the picture. A brief look into the documentation of the package indicates that hidedecorations and hidespines should do the trick.
function drawLogo()::Cmk.Figure
centersXs::Vec{Flt} = [1, 5.5, 10]
centersYs::Vec{Flt} = [1, 6, 1]
colors::Vec{Str} = ["red", "green", "purple"]
numOfPoints::Int = 3000
fig::Cmk.Figure = Cmk.Figure()
ax::Cmk.Axis = Cmk.Axis(fig[1, 1])
Cmk.hidedecorations!(ax)
Cmk.hidespines!(ax)
for i in eachindex(colors)
Cmk.scatter!(ax,
centersXs[i] .+ Rnd.randn(numOfPoints),
centersYs[i] .+ Rnd.randn(numOfPoints),
color=colors[i], markersize=10, alpha=0.25)
end
return fig
end
And voila.
Rnd.seed!(303) # needed to make it reproducible
drawLogo()
We obtained a decent replica of the original. Of course, kudos go to the authors of the original image for their creativity and artistic taste.