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.
- Crameri, F. (2018). Scientific colour maps. Zenodo. http://doi.org/10.5281/zenodo.1243862
- Crameri, F. (2018), Geodynamic diagnostics, scientific visualisation and StagLab 3.0, Geosci. Model Dev., 11, 2541-2562, https://doi.org/10.5194/gmd-11-2541-2018
- Crameri, F., G.E. Shephard, and P.J. Heron (2020), The misuse of colour in science communication, Nature Communications, 11, 5444. https://www.nature.com/articles/s41467-020-19160-7
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 DataPaclets
ColorDataDump` 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
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:
- I dont have a clear idea how to make
ColorData[{"Acton","Reverse"}]
or ColorData[{"Acton",{0,10}}]
work.
- Is hacking into the
DataPaclets
ColorDataDump` realy the best idea.
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
PS
An additional nice function is the ResourceFunction["DivergentColorFunction"]
.
Attachments: