我的应用程序包含一个可以一次显示20个或更多数据集的折线图,但通常显示的数据集少于5.我希望每个数据集都有一个独特的颜色。
目前我正在这样做:
setHsl(i * 255.0 / session->getNumDataSets(), 255, 128);
它有效,但缺点是两个连续的数据集将具有非常相似的颜色。我喜欢它,以便生成的每种颜色与所有以前生成的颜色尽可能形成对比。
生成颜色的更好方法是什么?
这是我的第二次尝试:
double pos = 0;
if (wheel.size() == 0)
{
wheel.append(0.0);
wheel.append(1.0);
}
else
{
double gap = 0;
double hi = 0;
double lo = 0;
for (int i = 0; i < wheel.size() - 1; i++)
{
double g = wheel[i + 1] - wheel[i];
if (g > gap)
{
gap = g;
lo = wheel[i];
hi = wheel[i + 1];
}
}
pos = (hi - lo) / 2.0 + lo;
wheel.append(pos);
qSort(wheel);
}
QColor c;
c.setHsl(pos * 255.0, 255, 128);
return c.toRgb();
我的想法是第一种颜色,是色轮上的位置0。然后对于每一种颜色,我绕着色轮,寻找颜色之间的最大差距,一旦我找到它,我就在那个间隙中插入一种新颜色。它似乎工作得更好,但仍然不是完美的,因为一旦间隙变小,连续的颜色会再次变得相似。
答案 0 :(得分:5)
我知道您正在寻找一种计算生成图形颜色的方法,但您可能需要考虑设计自定义调色板并从预先存储的表格中查找颜色。
这样做的好处是,您可以为色盲用户制作更容易区分的颜色选择。您可以使用VisCheck之类的工具来查看图表对色盲用户的显示效果。
如果您可能有超过20个数据集,我想可能很难仅通过颜色来区分,但颜色可以与其他微分器(如虚线)结合使用。
答案 1 :(得分:3)
您可以执行以下操作:
int n = session->getNumDataSets();
setHsl( (((i%3) * n/3)+(i/3)) * 255.0 / n, 255, 128);
我必须仔细检查我的数学,但基本上它会旋转三分之一。
答案 2 :(得分:2)
不要使用HSL。它的缺点是为什么在HSL(或者同样糟糕的,HSV)空间中数字“看起来不同”的颜色最终看起来与你的眼睛相似。而是使用YUV(又名YCbCr)。如果您不熟悉的话,YUV的基本思想是对第一轴为感知强度的坐标进行线性变换,如:
Y = 0.3*R + 0.6*G + 0.1*B
(通常使用更精细调整的系数,但这些是简单的系数,让您大致了解权重)
然后简单地选择第二和第三轴作为与Y轴正交的平面中的两个矢量,通常大致为“红色”和“蓝色”方向。
请注意,由于颜色仅限于RGB坐标中的立方体,因此一旦选择了Y值,就会对保留在框内的可能U和V值进行限制。在Y = max时,U和V必须为零。因此,只需选择一些中间亮度的Y值,其中你在U和V中有很多游戏,然后在UV平面的极坐标中选择N个均匀间隔的矢量。
答案 3 :(得分:2)
我在Java中使用以下函数为java生成的图形上的不同数据集创建等间距的颜色。简短而甜蜜:
/**
* This function splits the red-green-blue colour wheel into n equally spaced divisions
* and returns the colour from a particular division.
*
* @param index The index of the colour to return, the range is 0 - (count-1)
* @param count The number of divisions to split the HSV colour wheel into
* @return A java.awt.Color object containing the colour.
* @author HughesR
*/
public static Color getSpacedOutColour(int index, int count) {
final float saturation = 0.95f; // Saturation
final float brightness = 0.8f; // Brightness
float hue = (float)index / (float)count;
return Color.getHSBColor(hue, saturation, brightness);
}