Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

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 if 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.

share|improve this answer
1  
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. –  Alexey Popkov Aug 22 at 7:03
    
@Alexey That's a good idea though it is not what the OP asked for. I at least like to try to answer the actual question before or in addition to proposing alternatives. Have you already implemented something like that? –  Mr.Wizard Aug 22 at 7:07
1  
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. –  Alexey Popkov Aug 22 at 7:07
    
After re-reading the question I realized that dynamical loading of the color schemes may not be the best choice: it requires additional communication between the FrontEnd and the Kernel which easily can lead to significant delay and even hanging-up of the FrontEnd. I'll try to see if the file ColorSchemeSelector.tr is loaded only once for session or every time the user requests that menu. –  Alexey Popkov Aug 22 at 7:17
2  
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. –  Alexey Popkov Aug 22 at 7:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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