Message Boards Message Boards

Scientific color maps

I would be grateful if any of the coders here have some thoughts on how to improve upon what i did to get custom colormaps into Mathematica.

Back in 2018 Fabio Crameri proposed some good color maps for scientific visualization and recently V8 was released.

In the Readme the Mathematica integration is given by this code which works but needs to run every time and only one color function at a time.

ColorMapSuitePath = "/Path/To/ColourMapSuite/";
ColorMapSuite[name_String] := ColorMapSuite[name, -1]
ColorMapSuite[name_String, el_] := With[{
list =
Transpose@{Subdivide[0, 1, 255],
RGBColor @@@
First@Import[
ColorMapSuitePath <> "/" <> name <> "/" <> name <> ".mat"]}
},
Blend[list, {##}[[el]]] &
]

It was on my list for a long time but i have written some code that imports the color maps into mathematica but also integrates them in the ColorData functionality based on the following discussions from on stackexchange:

Which is a bit "hacky" by inserting things into the DataPacletsColorDataDump` but works. Regrettably, I could not find any nicer solutions for now to permanently store custom color functions in Mathematica. So i went on this path. The function i came up with is

AddScientificColours[dir_]:=Block[{
       grads,gradDiv,gradMulti,cyclic,all,swatches,colName,groupName,getCol,colRange,allDef,
       nameDef,groupDef,newGroupsPattern,newShemeNames,newShemes,scientificColorMapsGroups,gr
    },

    (*activated ColorDataDump*)
    ColorData[];

    (*sklip if either the files are not there or the colors have been difined already*)
    If[Quiet[Head[ColorData["ScientificColorMapsGroups"]]===ColorData]&&DirectoryQ[dir],

       (*color functions defined in scientific colour maps v8*)
       grads={"acton","bamako","batlow","batlowK","batlowW","bilbao","buda","davos","devon","glasgow","grayC","hawaii","imola","lajolla","lapaz","lipari","navia","nuuk","oslo","tokyo","turku"};
       gradDiv={"bam","berlin","broc","cork","lisbon","managua","roma","tofino","vanimo","vik"};
       gradMulti={"fes","bukavu","oleron"};
       cyclic={"bamO","brocO","corkO","romaO","vikO"};

       all=Join[grads,gradDiv,gradMulti,cyclic];

       (*number of swatches for each*)
       swatches={"10","25","50","100"};

       (*functions that generate the information needed for the named colorfunctions*)
       colName=Switch[#2,
         1, {Capitalize[#1],#1,{}},
         2, {Capitalize[#1]<>"Discrete"<>#3,#1<>" discrete "<>#3,{}},
         3, {Capitalize[#1]<>"Categorical",#1<>" categorical",{}}
       ]&;

       groupName={
         If[#2===1,"Gradients","Indexed"],
         "ScientificColorMaps",
         Which[
          MemberQ[grads,#1],"Sequential",
          MemberQ[gradDiv,#1],"Diverging",
          MemberQ[gradMulti,#1],"MultiSequential",
          MemberQ[cyclic,#1],"Cyclic"
         ]<>"Gradients"<>Switch[#2,1,"",2,"Discrete",3,"Categorical"]
       }&;

       getCol=Switch[#2,
         1, If[!MemberQ[gradMulti,#1],
          RGBColor/@Import[FileNameJoin[{dir,#1,#1}]<>".txt","Data"],
          Transpose@{Join[Subdivide[0.,0.5,127],Subdivide[0.5,1.,127]], RGBColor/@Import[FileNameJoin[{dir,#1,#1}]<>".txt","Data"]}],
         2, RGBColor[ToExpression@StringSplit[#][[1;;3]]/255]&/@Import[FileNameJoin[{dir,#1,"DiscretePalettes",#1}]<>#3<>".txt","Lines"][[3;;]],
         3, RGBColor/@Import[FileNameJoin[{dir,#1,"CategoricalPalettes",#1}]<>"S.txt","Data"]
       ]&;

       colRange=Switch[#1,
              1, {0, 1},
              2, {1, ToExpression[#2], 1},
              3, {1, 100, 1} 
          ]&;

       (*generate all color functions*)
       allDef=Flatten[Table[
         {colName[name,i,j], groupName[name,i,j], 1, colRange[i,j], getCol[name,i,j], ""}
       ,{name,all}, {i, If[MemberQ[grads,name], {1,2,3}, {1,2}]}, {j, If[i==2, swatches, {""}]}], 2];

       (*modify ColorDataDump*)
       nameDef=allDef[[All,1,1]];
       groupDef=DeleteCases[DeleteCases[DeleteDuplicates[Flatten[allDef[[All,2]]]],"Gradients"],"Indexed"];
       newGroupsPattern=Alternatives@@Join[DataPaclets`ColorDataDump`colorSchemeGroupsPattern/.Alternatives->List,groupDef];
       newShemeNames=Join[DataPaclets`ColorDataDump`colorSchemeNames,nameDef];
       newShemes=Join[DataPaclets`ColorDataDump`colorSchemes,allDef];

       DataPaclets`ColorDataDump`colorSchemeGroupsPattern=newGroupsPattern;
       DataPaclets`ColorDataDump`colorSchemeNames=newShemeNames;
       DataPaclets`ColorDataDump`colorSchemes=newShemes;

       (*Modify ColorData such it can display the Scientific color map groups*)
       scientificColorMapsGroups={"SequentialGradients","SequentialGradientsDiscrete","SequentialGradientsCategorical","DivergingGradients",
         "DivergingGradientsDiscrete","MultiSequentialGradients","MultiSequentialGradientsDiscrete",
         "CyclicGradients","CyclicGradientsDiscrete"};

       Unprotect[ColorData];
       ColorData["ScientificColorMapsGroups"]=scientificColorMapsGroups;
       (gr=#;ColorData[gr]=Sort[Pick[DataPaclets`ColorDataDump`colorSchemeNames,MemberQ[#,gr]&/@DataPaclets`ColorDataDump`colorSchemes[[All,2]],True]])&/@Prepend[scientificColorMapsGroups,"ScientificColorMaps"];
       Protect[ColorData];
    ]
]

This function adds all the functions to the ColorData functionality (but not the front end color picker). The folowing groups are added.

  • SequentialGradients
  • SequentialGradientsDiscrete
  • SequentialGradientsCategorical
  • DivergingGradients
  • DivergingGradientsDiscrete
  • MultiSequentialGradients
  • MultiSequentialGradientsDiscrete
  • CyclicGradients
  • CyclicGradientsDiscrete

enter image description here

It all feels a bit cumbersome how it all worked out and the definitions of the color functions are a bit messy. I'm curious if anyone has some tips and tricks regarding color functions for a more "clean" integration before i start making this into a repository function and/or paclet since there are some open issues, for example:

  1. I dont have a clear idea how to make ColorData[{"Acton","Reverse"}] or ColorData[{"Acton",{0,10}}] work.
  2. Is hacking into the DataPacletsColorDataDump` realy the best idea.

enter image description here

It would be nice if there would be a config file you can place somewhere with custom color functions that are picked up upon opening Mathematica. For the ones interested i added my full notebook for testing and more can be found here

enter image description here

enter image description here

enter image description here

enter image description here

PS

An additional nice function is the ResourceFunction["DivergentColorFunction"].

POSTED BY: Martijn Froeling
4 Replies

Nice. I've used the "hacky" DataPacletsColorDataDump` method for my own color schemes.

You implicitly raised a question:

It would be nice if there would be a config file you can place somewhere with custom color functions that are picked up upon opening Mathematica.

Do you mean the init.m file?

POSTED BY: Michael Rogers

Yes and no, The init.m file can handle the initial definitions and loading, but then there is still some code needed to hack into the DataPacletsColorDataDump. I was hoping to find the location where the color functions are defined and which functions actually generates the datadump. So inject the color definitions before Colordatadump is activated.

POSTED BY: Martijn Froeling

I'm not sure what you're doing differently from me. I have no trouble adding my own color scheme to the ColorData database in my init.m file. I used ColorData[1]; instead of ColorData[]; to load the built-in database, but I doubt that is significant.

In any case, the data is stored in binary format in the file (at least on a Mac):

$InstallationDirectory/SystemFiles/Kernel/SystemResources/64Bit/DataPaclets/ColorData.mx

Alternatively, you can locate the file with the following:

FileNameJoin[{System`Private`$SystemFileDir, 
   ContextToFileName["DataPaclets`ColorData`"]}] <> "x"

I don't think you can do much with the file though, other than load it and then amend the database. Or get WRI to accept your color schemes as part of the Mma distribution.

POSTED BY: Michael Rogers

Thanks, i will have a look to see what i can do there.

POSTED BY: Martijn Froeling
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract