I would like to make a function f(x,y)
that returns a color and give that to plot
to create the background of the plot.
Is there something close to this on one of the plotting packages?
Thanks.
I would like to make a function f(x,y)
that returns a color and give that to plot
to create the background of the plot.
Is there something close to this on one of the plotting packages?
Thanks.
You can just make a heatmap
for example?
EDIT: eg using Plots.jl
I want to give the plot a color to use at each x,y location, not a scalar that gets mapped to a color.
I did try heatmap
of Plots.jl
just in case it magically works, but it says it can’t convert ColorTypes.RGB
to Float64
.
Imagine I want to plot on one of these:
I realize this doesn’t do what you want, but maybe it’s helpful?
using ColorSchemes
using Makie
f(x,y) = RGB(x/255,y/255,x/2/255)
xs = 0:255
ys = 0:255
zs = xs .* ys'
colors = ColorScheme([f(x,y) for x in xs for y in ys])
image(xs,ys,zs, colormap=colors)
Outputs:
Oh that wasn’t clear.
In that case, do using Images
and make a matrix of your RGB objects. It should display as an image with those colours.
Oh yes, I used Colors.jl
functions to make the chromaticity diagram image I shared. I would like to be able to plot various things on top of that image, preferably in the x,y space so that axes are sensible.
However I’m fighting with blue screens of death tonight which isn’t making anything easier.
Would you be happy to share the code for that? It’s very nice.
Plots uses palettes. There should be a way to encode the colours into a palette so you can do the same with heatmap with axes.
There’s some hard coded scaling that could be generalized and I dislike the C,M,Y seams that appear more prominently in this than in other implementations but here you go:.
### A Pluto.jl notebook ###
# v0.12.18
using Markdown
using InteractiveUtils
# ╔═╡ 5ba5d640-5cd0-11eb-24d0-e3dbc6ed284b
begin
import Pkg
Pkg.activate(mktempdir())
Pkg.add("Colors"); using Colors
Pkg.add("PlutoUI"); using PlutoUI
Pkg.add("PolygonOps"); using PolygonOps
Pkg.add("ImageShow"); using ImageShow
Pkg.add("ImageIO"); using ImageIO
end
# ╔═╡ 982fe8a0-5cd8-11eb-3690-316355a4724a
monochromatic_locus = convert.( xyY, colormatch.(360:780))
# ╔═╡ d68fa790-5cef-11eb-062e-af9940a5a224
begin
polygon = [[c.x,c.y] for c in monochromatic_locus]
push!(polygon, polygon[1])
end;
# ╔═╡ c20e8ca0-5d12-11eb-114a-572c90ef9920
function chrom(x,y)
if inpolygon((x,y), polygon)==1
c = RGB(xyY(x,y,1e-6))
k = 1.0/maximum((c.r, c.g, c.b))
c = RGB(k*c.r, k*c.g, k*c.b)
else
c = RGB(0,0,0)
end
end
# ╔═╡ e8b02b80-5cf3-11eb-3882-a742b74e5f5c
chromdiag = let
chromdiag = fill(RGB(0,0,0),900, 800)
for x ∈ 1:800
for y ∈ 1:900
xf = x/1000
yf = y/1000
chromdiag[900-y+1,x] = chrom(xf,yf)
end
end
chromdiag
end
# ╔═╡ Cell order:
# ╠═e8b02b80-5cf3-11eb-3882-a742b74e5f5c
# ╠═c20e8ca0-5d12-11eb-114a-572c90ef9920
# ╠═d68fa790-5cef-11eb-062e-af9940a5a224
# ╠═982fe8a0-5cd8-11eb-3690-316355a4724a
# ╠═5ba5d640-5cd0-11eb-24d0-e3dbc6ed284b
This is excellent.
GR plots the resulting RGB array directly. Only setting the y-axis is a bit tricky because of the flipped y-axis due to the way chromdiag was constructed:
plot((1:800)/1000, (1:900)/1000, reverse(chromdiag,dims=1),xlabel="x",ylabel="y",yflip=false)
On this topic, the wikipedia article on CIE 1931 color space is worth taking a look at.
Awesome! Is the key to making that work that your x and y ranges match the image dimensions exactly?
Looks like exactly what I needed. Thanks!