Wolfram mathematica ArrayPlot中的自定义ColorFunction/ColorData(以及类似函数)

Wolfram mathematica ArrayPlot中的自定义ColorFunction/ColorData(以及类似函数),wolfram-mathematica,Wolfram Mathematica,这与西蒙的数学有关。虽然所有的解决方案都解决了在线形图中更改ColorData的问题,但我觉得讨论对在ContourPlot/ArrayPlot/Plot3D中更改ColorData没有多大帮助 TLDR:有没有办法让mma在ArrayPlot/ContourPlot/等中使用自定义颜色 考虑下面的示例函数:在Matlab中创建的函数 Sin(x^ 2 +y^ 3)< /> >: 现在,在mma中执行以下操作: xMax = 3; yMax = 3; img = Transpose@

这与西蒙的数学有关。虽然所有的解决方案都解决了在线形图中更改
ColorData
的问题,但我觉得讨论对在
ContourPlot
/
ArrayPlot
/
Plot3D
中更改
ColorData
没有多大帮助

TLDR:有没有办法让mma在ArrayPlot/ContourPlot/等中使用自定义颜色


考虑下面的示例函数:在Matlab中创建的函数<代码> Sin(x^ 2 +y^ 3)< /> >:

现在,在mma中执行以下操作:

xMax = 3; yMax = 3;
img = Transpose@
   Table[Sin[y ^3 + x^2], {x, -xMax, xMax, 0.01}, {y, -yMax, yMax, 
     0.01}];
plot = ArrayPlot[img, ColorFunction -> ColorData["Rainbow"], 
   AspectRatio -> 1, 
   FrameTicks -> {FindDivisions[{0, (img // Dimensions // First) - 1},
       4], FindDivisions[{0, (img // Dimensions // Last) - 1}, 4], 
     None, None}, 
   DataReversed -> 
    True] /. (FrameTicks -> {x_, 
      y_}) :> (FrameTicks -> {x /. {a_?NumericQ, b_Integer} :> {a, 
         2 xMax (b/((img // Dimensions // First) - 1) - 1/2)}, 
      y /. {a_?NumericQ, b_Integer} :> {a, 
         2 yMax (b/((img // Dimensions // Last) - 1) - 1/2)}})
我得到下面的图:

我更喜欢MATLAB中丰富、明亮的颜色,而不是mma的柔和/暗淡的颜色。如果我从MATLAB获得了colormap的RGB值,我如何让mma使用这些颜色

您可以在MATLAB中下载默认颜色贴图的RGB值,并将其作为

cMap = Transpose@Import["path-to-colorMapJet.mat", {"HDF5", 
      "Datasets", "cMap"}];
cMap
是介于
0
1
之间的
64x3
值数组

为了给你一些背景知识,这里有一些来自MathWorks的相关文本

彩色贴图是实数的m×3矩阵 介于0.0和1.0之间的数字。每行 是一个RGB向量,它定义了一个 颜色彩色贴图的第k行 定义第k种颜色,其中映射(k,:) =[r(k)g(k)b(k)]指定红色、绿色和蓝色的强度

这里是
map=cMap
,和
m=64

我试着戳一下
ColorDataFunction
,发现
ColorData
格式与
colormap
类似。但是,我不知道如何获得
ArrayPlot
来使用它(对于其他绘图函数,它应该是相同的)



另外,由于我在这里的练习纯粹是为了在mma中达到一个舒适的水平,类似于我在MATLAB中所做的,因此我非常感谢关于改进代码的评论和建议。具体地说,我不太满意我的“修复”帧标记的方法。。。当然,一定有更好/更简单的方法来做这件事。

用以下方法替换您的
ColorData[“Rainbow”]

Function[Blend[RGBColor @@@ cMap, Slot[1]]]
你会发现:


关于你的第二个问题,你可以这样做:

xMax = 3; yMax = 3;
img = Transpose@
   Table[Sin[y^3 + x^2], {x, -xMax, xMax, 0.01}, {y, -yMax, yMax, 
     0.01}];
plot = ArrayPlot[img, 
  ColorFunction -> Function[Blend[RGBColor @@@ cMap, Slot[1]]], 
  AspectRatio -> 1, FrameTicks -> Automatic, 
  DataRange -> {{-xMax, xMax}, {-yMax, yMax}}, DataReversed -> True]

但是你为什么不使用DensityPlot呢

DensityPlot[Sin[y^3 + x^2], {x, -xMax, xMax}, {y, -yMax, yMax}, 
 ColorFunction -> Function[Blend[RGBColor @@@ cMap, Slot[1]]], 
 PlotPoints -> 300]


编辑
请注意,在第二个图中,y范围标签是反向的。这是因为它考虑了DataReversed设置。ArrayPlot以与在屏幕上打印阵列内容时相同的顺序打印阵列的行。因此,第一行在顶部绘制,最后一行在底部绘制。高行值对应低y值,反之亦然。DataReversed->True纠正了这种现象,但在本例中,它也“纠正”了y值。一种解决方法是填充数组,从高y值向下填充低y值。在这种情况下,您不需要反转数据:

xMax = 3; yMax = 3;
img = Transpose@
   Table[Sin[y^3 + x^2], {x, -xMax, xMax, 0.01}, {y, 
     yMax, -yMax, -0.01}];
plot = ArrayPlot[img, 
  ColorFunction -> Function[Blend[RGBColor @@@ cMap, Slot[1]]], 
  AspectRatio -> 1, FrameTicks -> Automatic, 
  DataRange -> {{-xMax, xMax}, {-yMax, yMax}}]
(我希望这不是太晚的补遗。)

事实证明,为了与
Blend[]
一起使用,甚至不需要保留整个64个
RGBColor[]
指令集。
cMap
列的
ListPlot[]
s提供了一条线索,表明情况确实如此:

{rr, gg, bb} = Transpose[Rationalize[cMap]];
GraphicsGrid[{MapThread[
   ListPlot[#1, DataRange -> {0, 1}, Frame -> True, 
     GridLines -> {{1/9, 23/63, 13/21, 55/63}, None}, 
     PlotLabel -> #2] &, {{rr, gg, bb}, {"Red", "Green", "Blue"}}]}]

我们可以看到,隐式地,表示这些分量的函数是分段线性的。由于
Blend[]
必然会在颜色之间进行线性插值,如果我们能在分段线性图中找到对应于“角点”的颜色,我们就可以消除这些角点之间的所有其他颜色(因为
Blend[]
会为我们进行插值),因此可能只需要随身携带,比如,七种颜色,而不是六十四种颜色

通过阅读上面给出的代码,您会注意到我已经为您找到了这些转换点(提示:检查
网格线的设置)。关于这些颜色可能是什么的进一步提示由以下人员提供:

jet
的颜色范围从蓝色到红色,并通过青色、黄色和橙色

可能是吗?让我们检查一下:

cols = RGBColor @@@ Rationalize[cMap];
Position[cols, #][[1, 1]] & /@ {Blue, Cyan, Yellow, 
  Orange // Rationalize, Red}
{8, 24, 40, 48, 56}
这只是给出了数组
cols
中颜色的位置,但我们可以重新调整大小,使其与colormap预期的参数范围相对应:

(# - 1)/(Length[cols] - 1) & /@ %
{1/9, 23/63, 13/21, 47/63, 55/63}
这些正是与彩色贴图的RGB分量相对应的分段线性函数的断点所在。那就是五种颜色;为了确保平滑插值,我们还将第一个和最后一个颜色添加到此列表中

cols[[{1, Length[cols]}]]
{RGBColor[0, 0, 9/16], RGBColor[1/2, 0, 0]}
将原始的
cols
列表减少到总共七个。因为7/64大约是11%,这是一个相当大的节约

因此,我们寻求的颜色函数是

jet[u_?NumericQ] := Blend[
        {{0, RGBColor[0, 0, 9/16]}, {1/9, Blue}, {23/63, Cyan}, {13/21, Yellow},
         {47/63, Orange}, {55/63, Red}, {1, RGBColor[1/2, 0, 0]}}, 
                          u] /; 0 <= u <= 1

下面是一个机械验证,可以很好地再现
cols
中的64种颜色:

Rationalize[Table[jet[k/63], {k, 0, 63}]] === cols
True

您现在可以使用
jet[]
作为
ColorFunction
用于任何支持它的打印功能。享受吧

您是否尝试过使用ColorData[“LightTemperatureMap”]或ColorData[“TemperatureMap”]而不是“Rainbow”?这些产生了一个更加光明的情节。有比尤达更老的研究生顾问吗?@Sjoerd:太好了<代码>数据范围
为我节省了大量不必要的更换。你说得对,我也可以用
DensityPlot
来做。我只是默认为
ArrayPlot
,因为我从MATLAB(然后导入到mma)的所有输出都是数组。这只是一个函数形式简洁的例子。@Sjoerd:DataRange为什么翻转垂直轴?如果您查看答案中的最后两个绘图,yaxis记号会在
ArrayPlot
图中翻转。@Sjoerd:谢谢。我也可以使用
Reverse@
来处理我不按顺序控制填充的数组。@Mr.Wizard不,它是相同的。对所有将要使用该版本的人的一个警告:事实上,你必须小心括号在那里
Rationalize[Table[jet[k/63], {k, 0, 63}]] === cols
True