Этого можно достичь с помощью пользовательской цветовой карты. Но нужно позаботиться, чтобы сделать это надежно. Простое размещение новой красной ключевой точки в середине цветовой карты даст очень неправильные результаты ...: |
Я слегка изменил и задокументировал ваш пример. В принципе, в цветовых картах содержатся ключевые точки с положением и цветом. Позиции обычно (но не обязательно) варьируются от [0..1]. Цвета всегда находятся в диапазоне [0..1]. Задача здесь состоит в том, чтобы найти правильную позицию вашего значения «0» cdata в диапазоне цветовых диапазонов.
Во-первых, создайте стандартную цветовую карту Cool. Она имеет следующие два ключевые точки (в строках):
colorkeys
<Single> [2,5]
[0]: 0,00000 0,00000 1,00000 1,00000 1,00000 <- position: 0, color: RGBA
[1]: 1,00000 1,00000 0,00000 1,00000 1,00000 <- position: 1
Вы должны добавить по крайней мере 3 новые ключевые точки: первые два образца оригинального цвета по краям выделенной области. Третий дает отмеченную область красного цвета. Это не будет работать, чтобы просто добавить красную характерную точку, так как это будет влиять на все значения в карте, а не только значения данных около 0.
В конце концов ключевых точек выглядит следующим образом:
colorkeys
<Single> [5,5]
[0]: 0,00000 0,00000 1,00000 1,00000 1,00000
[1]: 1,00000 1,00000 0,00000 1,00000 1,00000
[2]: 0,49150 0,49150 0,50850 1,00000 1,00000
[3]: 0,49702 0,49702 0,50298 1,00000 1,00000
[4]: 0,49426 1,00000 0,00000 0,00000 1,00000
Обратите внимание, что порядок ключевых точек не важен. В любом случае они сортируются при создании новой цветовой карты. Новая карта просто предоставляется ILSurface:
private void ilPanel1_Load(object sender, EventArgs e) {
// create some X/Y meshgrid data
ILArray<float> y = 1, R = ILMath.linspace<float>(-4, 4, 100);
ILArray<float> x = ILMath.meshgrid(R, ILMath.linspace<float>(-4, 4, 100), y);
// precreate the surface data array
ILArray<float> Z = ILMath.zeros<float>(x.S[0], x.S[1], 3);
// surface expects Z, X and Y coords (in that order)
Z[":;:;2"] = y; Z[":;:;1"] = x;
Z[":;:;0"] = 0.4f * x * x - 0.2f * y * y * y;
// our color data are based on another function
ILArray<float> cdata = 1.4f * x * x * x + 0.13f * y * y;
// we need cdatas limits for creating a new colormap
float min, max; cdata.GetLimits(out min, out max);
// get default 'Cool' colormap
var colormap = new ILColormap(Colormaps.Cool);
// get colormap keys as array: [position,R,G,B,A]
ILArray<float> colorkeys = colormap.Data;
// helper function to map true values to 0..1 range
Func<float, float> map = a => { return (a - min)/(max - min); };
// the value to mark and +/- tolerance width (to make it a visible strip at least)
float markValue = 0, tolerance = 0.5f;
// sample the colormap at the marked edges
Vector4 key1 = colormap.Map(markValue - tolerance, new Tuple<float, float>(min, max));
Vector4 key2 = colormap.Map(markValue + tolerance, new Tuple<float, float>(min, max));
// create new keypoints at the edges of marked area
colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue - tolerance), key1.X, key1.Y, key1.Z, 1f);
colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue + tolerance), key2.X, key2.Y, key2.Z, 1f);
// create new keypoint for the marked area itself; color red
colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue), 1f, 0f, 0f, 1f); // red
// make a new colormap out of it
colormap = new ILColormap(colorkeys);
// create & add a plot cube
ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
// add surface plot, give custom colormap & colormap data ...
new ILSurface(Z, colormap: colormap, C: cdata) {
// add colorbar
Childs = { new ILColorbar() }
}
});
}
Это производит этот выход:
Большой материал! Но для меня это выглядит по-другому. Цвета не работают так гладко, как на картинке. Кажется, вы используете моно для рендеринга. Является ли это обычной дисперсией вывода между различными рендерами/фреймами? – user492238
Нет. Вывод * очень * похож на всех платформах, независимо от того, использует ли он OpenGL, GDI или SVG. Вероятно, вы испытали ошибку. Вот ссылка на последний RC: http://ilnumerics.net/release/EUJJRWPO225PlHDjW09/ILNumerics_v3.0_RCh.zip –
Работает для меня. Интересно, если то же самое нельзя было сделать и в индивидуальном цветовом режиме? Я имею в виду, если я дам каждой точке сетки отдельный цвет? –