How can I sample from a gradient color scheme palette in segments of a fixed color distance? I.e, the next element appended to the generated list is a fixed distance from the most recently added color in the list. I have an initial color and would like to make regular samples from a color palette starting from this initial color.
1 Answer
$\begingroup$
$\endgroup$
5
We can make a little helper function:
ClearAll[SampleGradientFixedColorDistance]
SampleGradientFixedColorDistance[cf_, n_, m_ : 250] :=
Module[{dists, vals, colors, if, max, newvals},
vals = N@Subdivide[m];
colors = cf /@ vals;
dists = BlockMap[Apply[ColorDistance], colors, 2, 1];
dists = Prepend[Accumulate[dists], 0];
max = Max[dists];
if = Interpolation[Transpose[{dists, vals}]];
newvals = if /@ Subdivide[0, max, n - 1];
cf /@ newvals
]
Which we can then call:
colors = SampleGradientFixedColorDistance[ColorData["Rainbow"], 20]
Compare it with linear sampling of the color scheme:
linearcolors = ColorData["Rainbow"] /@ Subdivide[20 - 1]
Now we can compare the distances between successive colors:
ListPlot[{BlockMap[Apply[ColorDistance], colors, 2, 1],
BlockMap[Apply[ColorDistance], linearcolors, 2, 1]},
PlotRange -> All, PlotLegends -> {"Adjusted", "Linear"},
Frame -> True]
It is not perfect, because color distances are not so nicely 'additive'. But it gives a reasonable improvement on the built-in.
-
$\begingroup$ Any way of modifying this to start at an arbitrary intial color? I realize some colors may not exist inside the palette but then I could just use FindMatchingColor. $\endgroup$– skyfireCommented Mar 14, 2020 at 16:42
-
$\begingroup$ I'm not sure if that makes 'sense': to which point in the scheme would you go? the first? If your first choice is 'too far' one can not guarantee that 'n' colors is possible… $\endgroup$– SHuismanCommented Mar 14, 2020 at 17:26
-
$\begingroup$ So I have the color
#c4d167
but would like to take samples of colors that are evenly spaced beginning at#c4d167
. I don't want any sort of "wrapping around" the gradient if that is what you are asking. But I think it shoulud be possible to take fixed sample segments to the right and to the left beginning at#c4d167
. $\endgroup$– skyfireCommented Mar 14, 2020 at 17:31 -
$\begingroup$ So starting at #c4d167 then move to the first color of the gradient, then continue taking steps of the same size in the gradient? $\endgroup$– SHuismanCommented Mar 14, 2020 at 17:40
-
$\begingroup$ Result would look like
colorset = {..., c - Δd, c, c + Δd,...}
wherec = #c4d167
andd
is the fixed color distance. $\endgroup$– skyfireCommented Mar 14, 2020 at 17:47
ResourceFunction[“SampleColors”]
$\endgroup$