36
$\begingroup$

Because of the standards in my field, for many plots I need to use (or at least end up using) rather narrowly defined colour schemes, and in particular the Matlab "Jet" scheme, which is well described in this SO answer. I've typically done this by having a bit of boilerplate code which I include when necessary, and which creates the object ColorData["Jet"]:

Unprotect[ColorData];
ColorData["Jet"] = 
  Function[x, 
   Blend[Transpose[{
        {0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0}, 
        {Darker[Blue], Blue, Cyan, Green, Yellow, Red, Darker[Red]}
   }], x]];
Protect[ColorData]

This is convenient because the new colour scheme can be handled using the same syntax as the in-built ones. In version 10, however, the choice of colour schemes has a bunch of additional niceties which I'd like to take advantage of it that's possible.

For example, the autocomplete menu for ColorDat... gives you instant access to a drop-down menu with images of the schemes' gradients, and which inserts ColorData["gradient-of-your-choice"] when you click OK.

enter image description here enter image description here

Similarly, when you evaluate such ColorData objects, they come out with a nice preview of the gradient.

enter image description here

So, my question is: is it possible to take advantage of this structure by 'injecting' additional data into ColorData, so that custom colour schemes come up in the choices and behave in the same way as in-built ones?

$\endgroup$
1
  • $\begingroup$ Related: (54648) $\endgroup$
    – Mr.Wizard
    Commented Jul 19, 2016 at 19:52

1 Answer 1

38
$\begingroup$

Extending ColorData

For some background consider reading this bookmarked conversation.

The color scheme data itself is accessed through the definition of this Symbol:

DataPaclets`ColorDataDump`colorSchemes

The data is located by use of the list defined in:

DataPaclets`ColorDataDump`colorSchemeNames

That is to say the scheme is extracted using (slightly simplified):

Pick[colorSchemes, colorSchemeNames, "SchemeName"]

Therefore these two sources must be kept synchronized.

These Symbols have no definition until ColorData (or similar) is first used therefore they must be "preloaded" before you make any modification or it will simply be overwritten during initialization.

Looking at the structure of one of the gradient entries in that data we can mimic it:

DataPaclets`ColorDataDump`colorSchemes[[150]]
{{"MintColors", "mint colors", {}}, {"Gradients"}, 1, {0, 1}, {RGBColor[
  0.465278, 0.97641, 0.637812], . . . RGBColor[0.913603, 0.61886, 0.788739]}, ""}

Customization:

ColorData[1];

new = {{"Primaries", "", {}}, {"Gradients"}, 
   1, {0, 1}, {Purple, Hue[0.6], Green, White, Yellow, Orange, Red}, ""};

AppendTo[
  DataPaclets`ColorDataDump`colorSchemes,
  new
];

AppendTo[
  DataPaclets`ColorDataDump`colorSchemeNames,
  new[[1, 1]]
];

Test:

ColorData["Primaries"]

enter image description here

So we can successfully add a gradient scheme. However this scheme does not appear in the Gradients pop-up menu shown in your question.

Extending the Color Scheme Selector

The Color Scheme Selector is loaded from the system file found here:

FileNameJoin[{$InstallationDirectory, 
  "SystemFiles/FrontEnd/TextResources/ColorSchemeSelector.tr"}]

Unfortunately I don't know of a way to extend this menu apart from editing that file. The elements are not dynamically loaded from colorSchemes but instead hard-coded directly in that file. The structure seems fairly apparent with repeating sections of the form:

"Rainbow" -> 
 Grid[{{Spacer[6], 
    Pane[Style["Rainbow", 10], {117, 14}, Alignment -> {Left, Center}, 
     ImageSizeAction -> "ShrinkToFit"], Spacer[6]}, {Spacer[6], 
    Graphics[Raster[
      CompressedData[
       "1:eJwVVH . . . "], {{0, 0}, {1, 0.17094017094017094`}}], {ImageSize -> {130, 
        Automatic}, ImageMargins -> {{0, 0}, {6, 0}}, ImagePadding -> 0, 
      PlotRangePadding -> 0}], Spacer[6]}}, {Alignment -> {Left, {Center, Top}}, 
   Frame -> None, ItemSize -> {{0.5, {2 -> Automatic}}, Automatic}, Spacings -> {0, 0}}]

I heavily abridged the CompressedData content for display here. As you can see the gradient is stored as a Raster rather than being generated from the gradient scheme itself.

That section formats as:

enter image description here

Later I shall try to find a way to modify this menu without editing this system file. (Edit: I never found a way.)

$\endgroup$
15
  • 1
    $\begingroup$ One option is to create a custom palette which will dynamically load the color schemes on startup. This way probably should be preferred over editing the built-in palette. $\endgroup$ Commented Aug 22, 2014 at 7:03
  • 2
    $\begingroup$ But it is rather interesting if you find a way to modify the loaded built-in palette on the fly in-memory without editing the file. $\endgroup$ Commented Aug 22, 2014 at 7:07
  • 2
    $\begingroup$ My quick experiments with Process Monitor show that unfortunately the file ColorSchemeSelector.tr is loaded from the disk every time a user requests the menu. $\endgroup$ Commented Aug 22, 2014 at 7:32
  • 2
    $\begingroup$ I have performed a search of sting "ColorSchemeSelector.tr" inside of Mathematica installation directory and found it only inside of the files "Mathematica.exe". It means that this name is hard-coded into the FrontEnd and cannot be changed. $\endgroup$ Commented Aug 22, 2014 at 9:03
  • 2
    $\begingroup$ Does anybody know what the lone 1 in ... {"Gradients"}, 1, {0,1} ... relates to? I can't see a value in that position that is not 1 in any of the gradients! $\endgroup$ Commented Nov 11, 2016 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.