2

It seems most references showing a CIE Yxy diagram can be reduced to very few (one?) sources. If I wanted to construct the diagram myself from some published measurement values, how would I do it?

I'm assuming there is some parametric function f(wavelength) giving a vector (x, y) for each f. But how would that function f look like?

Actually I wanted to construct a CIE Luv* diagram, but when knowing the (x, y) vectors for CIE Yxy, I could easily convert those to (u*, v*), right?

Update (2019-06-07):

Drawing the outline (spectral line) is one part of the problem. Another part of the problem is filling in the correct colors (I'm aware that no existing computer display device can actually present them): Is it OK to put the D65 white at its position and use Gouraud-Shaded Triangle Meshes to interpolate the area between two points on the spectral line and that white point (Example Image)?

In case it's OK, how would I fill the "non-spectral triangle" outlines by both ends of the spectral line and the white-point? Trying that I found out that the ends of the spectral line practically represent black, so the triangle came out much more black than purple, and opposed to all diagrams I've seen before, there's a discontinuity where the non-spectral colors are (Example Image)

As an experiment, I cut off the end of the spectrum to 435-645nm, and the transition from spectral to non-spectral colors is rather smooth then. (Example Image)

I'm unsure whether that effect described is due to using the wrong data, using the wrong type of interpolation, numeric effects of interpolation, or limited gamut of my screen device.

Insights?

closed as off-topic by Michael C, Hueco, scottbb, xiota, Olivier Jun 10 at 16:15

  • This question does not appear to be about photography within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • For each wavelength, get the CIEXYZ values from a table, Add them together and divide X and Y by the sum which yields x and y. Plot the point. Do the same for each wavelength. Connect the dots. Possible duplicate of photo.stackexchange.com/questions/53510/… – doug Jun 3 at 14:36
  • 4
    I'm voting to close this question as off-topic because as presented it has nothing to do with actually taking a photograph. – Michael C Jun 3 at 17:13
  • 1
    @Michael C: Please suggest where to ask the question: There is no generic "color" or "colormetry" site, so this is the site where most questions about CIE Yxy diagrams had been asked before. Also many questions are not about fundamentals, but very specific (individual) problems. Why not allow a generic question? I think any answer to this question will give significant insights to what the CIE Yxy diagram means... – U. Windl Jun 3 at 22:19
  • @doug: So I would need the XYZ CMFs (not the RGB CMFs) to start with? Those from "2-deg coordinates from 2-deg XYZ CMFs" at cvrl.org/ciexyzpr.htm? – U. Windl Jun 3 at 22:30
  • The 2 degree, 1931 chromaticity coordinates tables at your link have already been normalized. That is the XYZ values add up to 1. As a consequence, the XY values correspond to the xy coordinates of the classic, horseshoe CIE Chromaticity graph. Just plot the X and Y as dots for each wavelength and connect the dots. Then draw a straight line between the lower left and lower right points (violet to magenta ro red) which is just mixtures of the lowest and highest wavelengths. – doug Jun 3 at 22:47
2

The conversion path from CIE xyY to a given RGB colourspace, e.g. sRGB, is typically as follows:

CIE xyY --> CIE XYZ --> RGB

With that in mind, generating the diagram can be done by generating a regularly spaced 2D grid of samples in domain [0, 1] and apply the conversion path to them.

As you found out, no display device is capable of representing the visible spectrum, so you will be limited by its colorimetry boundaries.

Colour implements the three common Chromaticity Diagrams:

CIE 1931 Chromaticity Diagram CIE 1931 Chromaticity Diagram CIE 1960 UCS Chromaticity Diagram CIE 1960 UCS Chromaticity Diagram CIE 1976 UCS Chromaticity Diagram CIE 1976 UCS Chromaticity Diagram

The Python code for drawing the colours and bounding them with the spectral locus is as follows:

@override_style()
def plot_chromaticity_diagram_colours(
        samples=256,
        diagram_opacity=1.0,
        diagram_clipping_path=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        method='CIE 1931',
        **kwargs):
    """
    Plots the *Chromaticity Diagram* colours according to given method.

    Parameters
    ----------
    samples : numeric, optional
        Samples count on one axis.
    diagram_opacity : numeric, optional
        Opacity of the *Chromaticity Diagram* colours.
    diagram_clipping_path : array_like, optional
        Path of points used to clip the *Chromaticity Diagram* colours.
    cmfs : unicode, optional
        Standard observer colour matching functions used for
        *Chromaticity Diagram* bounds.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_chromaticity_diagram_colours()  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_Chromaticity_Diagram_Colours.png
        :align: center
        :alt: plot_chromaticity_diagram_colours
    """

    settings = {'uniform': True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    method = method.upper()

    cmfs = first_item(filter_cmfs(cmfs).values())

    illuminant = COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint

    ii, jj = np.meshgrid(
        np.linspace(0, 1, samples), np.linspace(1, 0, samples))
    ij = tstack([ii, jj])

    # NOTE: Various values in the grid have potential to generate
    # zero-divisions, they could be avoided by perturbing the grid, e.g. adding
    # a small epsilon. It was decided instead to disable warnings.
    with suppress_warnings(python_warnings=True):
        if method == 'CIE 1931':
            XYZ = xy_to_XYZ(ij)
            spectral_locus = XYZ_to_xy(cmfs.values, illuminant)
        elif method == 'CIE 1960 UCS':
            XYZ = xy_to_XYZ(UCS_uv_to_xy(ij))
            spectral_locus = UCS_to_uv(XYZ_to_UCS(cmfs.values))
        elif method == 'CIE 1976 UCS':
            XYZ = xy_to_XYZ(Luv_uv_to_xy(ij))
            spectral_locus = Luv_to_uv(
                XYZ_to_Luv(cmfs.values, illuminant), illuminant)
        else:
            raise ValueError(
                'Invalid method: "{0}", must be one of '
                '{{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}}'.format(
                    method))

    RGB = normalise_maximum(
        XYZ_to_plotting_colourspace(XYZ, illuminant), axis=-1)

    polygon = Polygon(
        spectral_locus
        if diagram_clipping_path is None else diagram_clipping_path,
        facecolor='none',
        edgecolor='none')
    axes.add_patch(polygon)
    # Preventing bounding box related issues as per
    # https://github.com/matplotlib/matplotlib/issues/10529
    image = axes.imshow(
        RGB,
        interpolation='bilinear',
        extent=(0, 1, 0, 1),
        clip_path=None,
        alpha=diagram_opacity)
    image.set_clip_path(polygon)

    settings = {'axes': axes}
    settings.update(kwargs)

    return render(**kwargs)

It is obviously dependent on a lot of Colour functions but it should be enough to illustrate the algorithm.

  • I found out that I actually use different colors as the rest (it seems): If you look at my plot, it even seems to look a bit three-dimensional, like viewing the RGB-cube from the white corner. That is, because I projected the XYZ colors to the X + Y + Z = 1 plane instead of using the colors in that plane. – U. Windl Jun 9 at 21:39
  • Note that we are normalising the RGB colours on the maximum value of each RGB triplet but there are no defined rules on how the normalisation should be done. Colour scientists tend to prefer to not use colours at all in chromaticity diagrams because they can be misleading. – Kel Solaar Jun 10 at 1:41
0

You can find the coordinates to plot for all of the CIE Standards on the Web at the Color & Vision Research Laboratory
They are available as CSV (Comma separated variables) suitable for Excel or other applications.

Good luck

  • Actually I've been there (Color & Vision Research Laboratory) weeks before asking this question. Which data exactly are you referring to, or do you just guess that data might be there? – U. Windl Jun 3 at 22:14
  • @U.Windl Navigate to the site, locate the plot you want, and click on the blue encircled "i" to reveal (in a drop-down page) the formulas to construct the plot data for each wavelength you wish. – Stan Jun 3 at 22:47
  • Unfortunately the site has at least two issues: 1) Navigating does not change the URL displayed (due to using frames). 2) The formula display seems to work correctly only with Microsoft IE: With Firefox I need to scroll to see the formulas. – U. Windl Jun 3 at 23:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.