Esempio n. 1
0
def _plot_target_vs_predicted_lab(labtarget, labpredicted, cspace = 'lab', verbosity = 1):
    """ Make a plot of target vs predicted color coordinates """
    if verbosity > 0:
        xylabels = _CSPACE_AXES[cspace]
        laball = np.vstack((labtarget,labpredicted))
        ml,ma,mb = laball.min(axis=0)
        Ml,Ma,Mb = laball.max(axis=0)
        fml = 0.95*ml
        fMl = 1.05*Ml
        fma = 1.05*ma if ma < 0 else 0.95*ma
        fMa = 0.95*Ma if Ma < 0 else 1.05*Ma
        fmb = 1.05*mb if mb < 0 else 0.95*mb
        fMb = 0.95*Mb if Mb < 0 else 1.05*Mb
        fig,(ax0,ax1,ax2) = plt.subplots(nrows=1,ncols=3, figsize = (15,4))
        ax0.plot(labtarget[...,1],labtarget[...,2],'bo',label = 'target')
        ax0.plot(labpredicted[...,1],labpredicted[...,2],'ro',label = 'predicted')
        ax0.axis([fma,fMa,fmb,fMb])
        ax1.plot(labtarget[...,1],labtarget[...,0],'bo',label = 'target')
        ax1.plot(labpredicted[...,1],labpredicted[...,0],'ro',label = 'predicted')
        ax1.axis([fma,fMa,fml,fMl])
        ax2.plot(labtarget[...,2],labtarget[...,0],'bo',label = 'target')
        ax2.plot(labpredicted[...,2],labpredicted[...,0],'ro',label = 'predicted')
        ax2.axis([fmb,fMb,fml,fMl])
        ax0.set_xlabel(xylabels[1])
        ax0.set_ylabel(xylabels[2])
        ax1.set_xlabel(xylabels[1])
        ax1.set_ylabel(xylabels[0])
        ax2.set_xlabel(xylabels[2])
        ax2.set_ylabel(xylabels[0])
        ax2.legend(loc='upper left')
Esempio n. 2
0
def _plot_DEs_vs_digital_values(DEslab, DEsl, DEsab, rgbcal, avg = lambda x: ((x**2).mean()**0.5), nbit = 8, verbosity = 1):
    """ Make a plot of the lab, l and ab color differences for the different calibration stimulus types. """
    if verbosity > 0:
        p_pure = [(rgbcal[:,1]==0) & (rgbcal[:,2]==0), 
              (rgbcal[:,0]==0) & (rgbcal[:,2]==0), 
              (rgbcal[:,0]==0) & (rgbcal[:,1]==0)] 
        p_grays = (rgbcal[:,0] == rgbcal[:,1]) & (rgbcal[:,0] == rgbcal[:,2])
        p_whites = (rgbcal[:,0] == (2**nbit-1)) & (rgbcal[:,1] == (2**nbit-1)) & (rgbcal[:,2] == (2**nbit-1))
        p_cyans = (rgbcal[:,0]==0) & (rgbcal[:,1]!=0) & (rgbcal[:,2]!=0)
        p_yellows = (rgbcal[:,0]!=0) & (rgbcal[:,1]!=0) & (rgbcal[:,2]==0)
        p_magentas = (rgbcal[:,0]!=0) & (rgbcal[:,1]==0) & (rgbcal[:,2]==0)
        fig,(ax0,ax1,ax2) = plt.subplots(nrows=1,ncols=3, figsize = (15,4))
        rgb_colors='rgb'
        rgb_labels=['red','green','blue']
        marker ='o'
        markersize = 10
        if p_whites.any():
            ax0.plot(rgbcal[p_whites,0], DEslab[p_whites],'ks',markersize = markersize, label='white')
            ax1.plot(rgbcal[p_whites,0], DEsl[p_whites],'ks',markersize = markersize,label='white')
            ax2.plot(rgbcal[p_whites,0], DEsab[p_whites],'ks',markersize = markersize,label='white')
        if p_grays.any():
            ax0.plot(rgbcal[p_grays,0], DEslab[p_grays], color = 'gray', marker = marker,linestyle='none',label='gray')
            ax1.plot(rgbcal[p_grays,0], DEsl[p_grays], color = 'gray', marker = marker,linestyle='none',label='gray')
            ax2.plot(rgbcal[p_grays,0], DEsab[p_grays], color = 'gray', marker = marker,linestyle='none',label='gray')
        for i in range(3):
            if p_pure[i].any():
                ax0.plot(rgbcal[p_pure[i],i], DEslab[p_pure[i]],rgb_colors[i]+marker,label=rgb_labels[i])
                ax1.plot(rgbcal[p_pure[i],i], DEsl[p_pure[i]],rgb_colors[i]+marker,label=rgb_labels[i])
                ax2.plot(rgbcal[p_pure[i],i], DEsab[p_pure[i]],rgb_colors[i]+marker,label=rgb_labels[i])
        if p_cyans.any():
            ax0.plot(rgbcal[p_cyans,1], DEslab[p_cyans],'c'+marker,label='cyan')
            ax1.plot(rgbcal[p_cyans,1], DEsl[p_cyans],'c'+marker,label='cyan')
            ax2.plot(rgbcal[p_cyans,1], DEsab[p_cyans],'c'+marker,label='cyan')
        if p_yellows.any():
            ax0.plot(rgbcal[p_yellows,0], DEslab[p_yellows],'y'+marker,label='yellow')
            ax1.plot(rgbcal[p_yellows,0], DEsl[p_yellows],'y'+marker,label='yellow')
            ax2.plot(rgbcal[p_yellows,0], DEsab[p_yellows],'y'+marker,label='yellow')
        if p_magentas.any():
            ax0.plot(rgbcal[p_magentas,0], DEslab[p_magentas],'m'+marker,label='magenta')
            ax1.plot(rgbcal[p_magentas,0], DEsl[p_magentas],'m'+marker,label='magenta')
            ax2.plot(rgbcal[p_magentas,0], DEsab[p_magentas],'m'+marker,label='magenta')
        ax0.plot(np.array([0,(2**nbit-1)*1.05]),np.hstack((avg(DEslab),avg(DEslab))),color = 'r',linewidth=2,linestyle='--')
        ax0.set_xlabel('digital values')
        ax0.set_ylabel('Color difference DElab')
        ax0.axis([0,(2**nbit-1)*1.05,0,max(DEslab)*1.1])
        ax0.set_title('DElab')
        ax1.plot(np.array([0,(2**nbit-1)*1.05]),np.hstack((avg(DEsl),avg(DEsl))),color = 'r',linewidth=2,linestyle='--')
        ax1.set_xlabel('digital values')
        ax1.set_ylabel('Color difference DEl')
        ax1.axis([0,(2**nbit-1)*1.05,0,max(DEslab)*1.1])
        ax1.set_title('DEl')
        ax2.plot(np.array([0,(2**nbit-1)*1.05]),np.hstack((avg(DEsab),avg(DEsab))),color = 'r',linewidth=2,linestyle='--')
        ax2.set_xlabel('digital values')
        ax2.set_ylabel('Color difference DEab')
        ax2.set_title('DEab')
        ax2.axis([0,(2**nbit-1)*1.05,0,max(DEslab)*1.1])
        ax2.legend(loc='upper left')
Esempio n. 3
0
def plot_tm30_Rxhj(spd, cri_type = 'ies-tm30', axh = None, figsize = (6,15),
                   font_size = _TM30_FONT_SIZE, **kwargs):
    """
    Plot Local Chroma Shifts (Rcshj), Local Hue Shifts (Rhshj) and Local Color Fidelity values (Rfhj) (one for each hue-bin).
    
    Args:
        :spd:
            | ndarray or dict
            | If ndarray: single spectral power distribution.
            | If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
            |  required keys:
            |   'Rf','Rg','cct','duv','Sr','cri_type','xyzri','xyzrw',
            |   'hbinnrs','Rfi','Rfhi','Rcshi','Rhshi',
            |   'jabt_binned','jabr_binned',
            |   'nhbins','start_hue','normalize_gamut','normalized_chroma_ref'
            | see cri.spd_to_cri() for more info on parameters.
        :cri_type:
            | _CRI_TYPE_DEFAULT or str or dict, optional
            |   -'str: specifies dict with default cri model parameters 
            |     (for supported types, see luxpy.cri._CRI_DEFAULTS['cri_types'])
            |   - dict: user defined model parameters 
            |     (see e.g. luxpy.cri._CRI_DEFAULTS['cierf'] 
            |     for required structure)
            | Note that any non-None input arguments (in kwargs) 
            | to the function will override default values in cri_type dict.
        :axh: 
            | None, optional
            | If None: create new figure with single axes, else plot on specified axes. 
        :figsize:
            | (6,15), optional
            | Figure size of pyplot figure.
        :font_size:
            | _TM30_FONT_SIZE, optional
            | Font size of text, axis labels and axis values.
        :kwargs:
            | Additional optional keyword arguments, 
            | the same as in cri.spd_to_cri()
            
    Returns:
        :axh: 
            | handle to figure axes.
        :data:
            | dictionary with required parameters for plotting functions.     
    """

    data = _tm30_process_spd(spd, cri_type = 'ies-tm30',**kwargs)
    
    if axh is None:
        fig, axh = plt.subplots(nrows = 3, ncols = 1, sharex = True, figsize = figsize)
    
    plot_tm30_Rcshj(data, axh = axh[0], xlabel = False, y_offset = 0.02, font_size = font_size)
    plot_tm30_Rhshj(data, axh = axh[1], xlabel = False, y_offset = 0.03, font_size = font_size)
    plot_tm30_Rfhj(data, axh = axh[2], xlabel = True, y_offset = 2, font_size = font_size)
    return axh, data
Esempio n. 4
0
def plot_rgb_color_patches(rgb,
                           patch_shape=(100, 100),
                           patch_layout=None,
                           ax=None,
                           show=True):
    """
    Create (and plot) an image with patches with specified rgb values.
    
    Args:
        :rgb:
            | ndarray with rgb values for each of the patches
        :patch_shape:
            | (100,100), optional
            | shape of each of the patches in the image
        :patch_layout:
            | None, optional
            | If None: layout is calculated automatically to give a 'good' aspect ratio
        :ax:
            | None, optional
            | Axes to plot the image in. If None: a new axes is created.
        :show:
            | True, optional
            | If True: plot image in axes and return axes handle; else: return ndarray with image.
            
    Return:
        :ax: or :imagae: 
            | Axes is returned if show == True, else: ndarray with rgb image is returned.
    """
    if ax is None:
        fig, ax = plt.subplots(1, 1)

    if patch_layout is None:
        patch_layout = get_subplot_layout(rgb.shape[0])

    image = np.zeros(
        np.hstack((np.array(patch_shape) * np.array(patch_layout), 3)))
    for i in range(rgb.shape[0]):
        r, c = np.unravel_index(i, patch_layout)
        R = int(r * patch_shape[0])
        C = int(c * patch_shape[1])
        image[R:R + patch_shape[0],
              C:C + patch_shape[1], :] = np.ones(np.hstack(
                  (patch_shape, 3))) * rgb[i, None, :]

    if show == False:
        return image
    else:
        ax.imshow(image.astype('uint8'))
        ax.axis('off')
        return ax
Esempio n. 5
0
def plotcircle(center=np.array([[0., 0.]]),
               radii=np.arange(0, 60, 10),
               angles=np.arange(0, 350, 10),
               color='k',
               linestyle='--',
               out=None,
               axh=None,
               **kwargs):
    """
    Plot one or more concentric circles.
    
    Args:
        :center: 
            | np.array([[0.,0.]]) or ndarray with center coordinates, optional
        :radii:
            | np.arange(0,60,10) or ndarray with radii of circle(s), optional
        :angles:
            | np.arange(0,350,10) or ndarray with angles (°), optional
        :color:
            | 'k', optional
            | Color for plotting.
        :linestyle:
            | '--', optional
            | Linestyle of circles.
        :out: 
            | None, optional
            | If None: plot circles, return (x,y) otherwise.
    """
    xs = np.array([0])
    ys = xs.copy()
    if ((out != 'x,y') & (axh is None)):
        fig, axh = plt.subplots(rows=1, ncols=1)
    for ri in radii:
        x = center[:, 0] + ri * np.cos(angles * np.pi / 180)
        y = center[:, 1] + ri * np.sin(angles * np.pi / 180)
        xs = np.hstack((xs, x))
        ys = np.hstack((ys, y))
        if (out != 'x,y'):
            axh.plot(x, y, color=color, linestyle=linestyle, **kwargs)
    if out == 'x,y':
        return xs, ys
    elif out == 'axh':
        return axh
Esempio n. 6
0
    print('New image shape:', im.shape)

    # simulate HR hyperspectral image:
    hrhsi = render_image(im, show=False)
    wlr = getwlr([380, 780, 1])  #  = wavelength range of default TM30 rfl set
    wlr = wlr[20:-80:10]  # wavelength range from 400nm-700nm every 10 nm
    hrhsi = hrhsi[...,
                  20:-80:10]  # wavelength range from 400nm-700nm every 10 nm
    print('Simulated HR-HSI shape:', hrhsi.shape)
    # np.save(file[:-4]+'.npy',{'hrhsi':hrhsi,'im':im, 'wlr':wlr})

    # Illumination spectrum of HSI:
    eew = np.vstack((wlr, np.ones_like(wlr)))

    # Create fig and axes for plots:
    if verbosity > 0: fig, axs = plt.subplots(1, 3)

    # convert HR hsi to HR rgb image:
    hrci = hsi_to_rgb(hrhsi,
                      spd=eew,
                      cieobs=cieobs,
                      wl=wlr,
                      linear_rgb=linear_rgb)
    if verbosity > 0: axs[0].imshow(hrci)

    # create LR hsi image for testing:
    dl = n
    lrhsi = hrhsi[::dl, ::dl, :]
    print('Simulated LR-HSI shape:', lrhsi.shape)

    # convert LR hsi to LR rgb image:
Esempio n. 7
0
def plot_cmfs(cmfs,
              cmf_symbols=['x', 'y', 'z'],
              cmf_label='',
              ylabel='Sensitivity',
              wavelength_bar=True,
              colors=['r', 'g', 'b'],
              axh=None,
              legend=True,
              **kwargs):
    """
    Plot CMFs.
    
    Args:
        :cmfs: 
            | ndarray with a set of CMFs.
        :cmf_symbols:
            | ['x,'y','z], optional
            | Symbols of the CMFs
            | If not a list but a string, the same label will be used for all CMF
            | and the same color will be used ('k' if colors is a list)
        :cmf_label:
            | '', optional
            | Additional label that will be added in front of the cmf symbols.
        :ylabel:
            | 'Sensitivity', optional
            | label for y-axis.
        :wavelength_bar:
            | True, optional
            | Add a colored wavelength bar with spectral colors.
        :colors:
            | ['r','g','b'], optional
            | Color for plotting each of the individual CMF.
        :axh:
            | None, optional
            | Axes to plot the image in. If None: a new axes is created.
        :kwargs:
            | additional kwargs for plt.plot().
            
    Returns:
        :axh:
            | figure axes handle.
    """
    if isinstance(cmf_symbols, list):
        cmf_symbols = [
            '$\overline{' + cmf_symbols[i][0] + '}' + cmf_symbols[i][1:] +
            '(\lambda)$' for i in range(3)
        ]
    else:
        cmf_symbols = [cmf_symbols, None, None]
        if isinstance(colors, list):
            colors = ['k'] * 3
        else:
            colors = [colors] * 3
    if axh is None:
        fig, axh = plt.subplots(1, 1)

    for i in range(3):
        label = cmf_label + cmf_symbols[i] if cmf_symbols[
            i] is not None else None
        axh.plot(cmfs[0], cmfs[i + 1], color=colors[i], label=label, **kwargs)

    if wavelength_bar == True:
        axh = plot_spectrum_colors(spd=None,
                                   spdmax=cmfs[1:].max(),
                                   axh=axh,
                                   wavelength_height=-0.05)
    axh.set_xlabel('Wavelength (nm)')
    axh.set_ylabel(ylabel)
    if legend == True:
        axh.legend()
    axh.grid(False)
    return axh
Esempio n. 8
0
def plot_tm30_Rhshj(spd, cri_type = 'ies-tm30', axh = None, 
                    xlabel = True, y_offset = 0, 
                    font_size = _TM30_FONT_SIZE, **kwargs):
    """
    Plot Local Hue Shift values (Rhshj) (one for each hue-bin).
    
    Args:
        :spd:
            | ndarray or dict
            | If ndarray: single spectral power distribution.
            | If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
            |  required keys:
            |   'Rf','Rg','cct','duv','Sr','cri_type','xyzri','xyzrw',
            |   'hbinnrs','Rfi','Rfhi','Rcshi','Rhshi',
            |   'jabt_binned','jabr_binned',
            |   'nhbins','start_hue','normalize_gamut','normalized_chroma_ref'
            | see cri.spd_to_cri() for more info on parameters.
        :cri_type:
            | _CRI_TYPE_DEFAULT or str or dict, optional
            |   -'str: specifies dict with default cri model parameters 
            |     (for supported types, see luxpy.cri._CRI_DEFAULTS['cri_types'])
            |   - dict: user defined model parameters 
            |     (see e.g. luxpy.cri._CRI_DEFAULTS['cierf'] 
            |     for required structure)
            | Note that any non-None input arguments (in kwargs) 
            | to the function will override default values in cri_type dict.
        :axh: 
            | None, optional
            | If None: create new figure with single axes, else plot on specified axes. 
        :xlabel:
            | True, optional
            | If False: don't add label and numbers to x-axis 
            | (useful when plotting plotting all 'Local Rfhi, Rcshi, Rshhi' 
            |  values in 3x1 subplots with 'shared x-axis': saves vertical space)
        :y_offset:
            | 0, optional
            | text-offset from top of bars in barplot.
        :font_size:
            | _TM30_FONT_SIZE, optional
            | Font size of text, axis labels and axis values.
        :kwargs:
            | Additional optional keyword arguments, 
            | the same as in cri.spd_to_cri()
            
    Returns:
        :axh: 
            | handle to figure axes.
        :data:
            | dictionary with required parameters for plotting functions.     
    """

    
    data = _tm30_process_spd(spd, cri_type = 'ies-tm30',**kwargs)
    Rhshi = data['Rhshi']

    # Get color map based on sample colors:
    cmap = _get_hue_map(hbins = data['nhbins'], start_hue = data['start_hue'], 
                        hbinnrs = data['hbinnrs'], 
                        xyzri = data['xyzri'], 
                        xyzrw = data['xyzrw'], 
                        cri_type = data['cri_type'])
    
    # Plot local hue shift, Rhshi:
    hbins = range(data['nhbins'])
    if axh is None:
        fig, axh = plt.subplots(nrows = 1, ncols = 1)
    for j in hbins:
        axh.bar(hbins[j],Rhshi[j,0], color = cmap[j], width = 1,edgecolor = 'k', alpha = 1)
        ypos = ((np.abs(Rhshi[j,0]) + 0.05 + y_offset))*np.sign(Rhshi[j,0])
        axh.text(hbins[j],ypos, '{:1.2f}'.format(Rhshi[j,0]) ,fontsize = font_size,horizontalalignment='center',verticalalignment='center',color = np.array([1,1,1])*0.3, rotation = 90)
    
    xticks = np.array(hbins)
    axh.set_xticks(xticks)
    if xlabel == True:
        xtickslabels = ['{:1.0f}'.format(ii+1) for ii in hbins]
        axh.set_xlabel('Hue-Angle Bin (j)', fontsize = font_size)
    else:
        xtickslabels = [''.format(ii+1) for ii in hbins]
    axh.set_xticklabels(xtickslabels, fontsize = font_size)
    axh.set_xlim([-0.5,data['nhbins']-0.5])
    
    axh.set_ylabel(r'Local Hue Shift $(R_{hs,hj})$', fontsize = 9)
    axh.set_ylim([min([-0.5,Rhshi.min()]),max([0.5,Rhshi.max()])])
    
    return axh, data
Esempio n. 9
0
def plot_tm30_Rfi(spd, cri_type = 'ies-tm30', axh = None, 
                  font_size = _TM30_FONT_SIZE, **kwargs):
    """
    Plot Sample Color Fidelity values (Rfi).
    
    Args:
        :spd:
            | ndarray or dict
            | If ndarray: single spectral power distribution.
            | If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
            |  required keys:
            |   'Rf','Rg','cct','duv','Sr','cri_type','xyzri','xyzrw',
            |   'hbinnrs','Rfi','Rfhi','Rcshi','Rhshi',
            |   'jabt_binned','jabr_binned',
            |   'nhbins','start_hue','normalize_gamut','normalized_chroma_ref'
            | see cri.spd_to_cri() for more info on parameters.
        :cri_type:
            | _CRI_TYPE_DEFAULT or str or dict, optional
            |   -'str: specifies dict with default cri model parameters 
            |     (for supported types, see luxpy.cri._CRI_DEFAULTS['cri_types'])
            |   - dict: user defined model parameters 
            |     (see e.g. luxpy.cri._CRI_DEFAULTS['cierf'] 
            |     for required structure)
            | Note that any non-None input arguments (in kwargs) 
            | to the function will override default values in cri_type dict.
        :axh: 
            | None, optional
            | If None: create new figure with single axes, else plot on specified axes.    
        :font_size:
            | _TM30_FONT_SIZE, optional
            | Font size of text, axis labels and axis values.
        :kwargs:
            | Additional optional keyword arguments, 
            | the same as in cri.spd_to_cri()
            
    Returns:
        :axh: 
            | handle to figure axes.
        :data:
            | dictionary with required parameters for plotting functions.     
    """
    data = _tm30_process_spd(spd, cri_type = 'ies-tm30',**kwargs)
    Rfi = data['Rfi']
    
    # get rgb values representing each sample:
    N = data['xyzri'].shape[0]
    xyzw = spd_to_xyz(_CIE_D65, relative = True, cieobs = data['cri_type']['cieobs']['xyz'])
    xyzri = cat.apply(data['xyzri'][:,0,:],xyzw1 = data['xyzrw'], xyzw2 = xyzw)
    rgbri = xyz_to_srgb(xyzri)/255
    
    # Create color map:
    cmap = []
    for i in range(N):
        cmap.append(rgbri[i,...])

    # Plot sample color fidelity, Rfi:
    if axh is None:
        fig, axh = plt.subplots(nrows = 1, ncols = 1)
    for j in range(N):
        axh.bar(j,Rfi[j,0], color = cmap[j], width = 1,edgecolor = None, alpha = 0.9)
        #axh.text(j,Rfi[j,0]*1.1, '{:1.0f}'.format(Rfi[j,0]) ,fontsize = 9,horizontalalignment='center',verticalalignment='center',color = np.array([1,1,1])*0.3)
    xticks = np.arange(0,N,step=2)
    xtickslabels = ['CES{:1.0f}'.format(ii+1) for ii in range(0,N,2)]
    axh.set_xticks(xticks)
    axh.set_xticklabels(xtickslabels, fontsize = font_size, rotation = 90)
    axh.set_ylabel(r'Color Sample Fidelity $(R_{f,CESi})$', fontsize = font_size)
    axh.set_ylim([0,100])
    axh.set_xlim([-0.5,N-0.5])
    
    return axh, data
Esempio n. 10
0
def plot_tm30_spd(spd, cri_type = 'ies-tm30', axh = None, 
                  font_size = _TM30_FONT_SIZE, **kwargs):
    """
    Plot test SPD and reference illuminant, both normalized to the same luminous power.
    
    Args:
        :spd:
            | ndarray or dict
            | If ndarray: single spectral power distribution.
            | If dict: dictionary with pre-computed parameters (using _tm30_process_spd()).
            |  required keys:
            |   'Rf','Rg','cct','duv','Sr','cri_type','xyzri','xyzrw',
            |   'hbinnrs','Rfi','Rfhi','Rcshi','Rhshi',
            |   'jabt_binned','jabr_binned',
            |   'nhbins','start_hue','normalize_gamut','normalized_chroma_ref'
            | see cri.spd_to_cri() for more info on parameters.
        :cri_type:
            | _CRI_TYPE_DEFAULT or str or dict, optional
            |   -'str: specifies dict with default cri model parameters 
            |     (for supported types, see luxpy.cri._CRI_DEFAULTS['cri_types'])
            |   - dict: user defined model parameters 
            |     (see e.g. luxpy.cri._CRI_DEFAULTS['cierf'] 
            |     for required structure)
            | Note that any non-None input arguments (in kwargs) 
            | to the function will override default values in cri_type dict.
        :axh: 
            | None, optional
            | If None: create new figure with single axes, else plot on specified axes.   
        :font_size:
            | _TM30_FONT_SIZE, optional
            | Font size of text, axis labels and axis values.
        :kwargs:
            | Additional optional keyword arguments, 
            | the same as in cri.spd_to_cri()
            
    Returns:
        :axh: 
            | handle to figure axes.
        :data:
            | dictionary with required parameters for plotting functions.  
  
    """

    data = _tm30_process_spd(spd, cri_type = 'ies-tm30',**kwargs)
    
    # Normalize Sr to same luminous power as spd:
    Phiv_spd = spd_to_power(data['spd'], ptype = 'pu', cieobs = data['cri_type']['cieobs']['cct'])
    #Phiv_Sr = spd_to_power(data['Sr'], ptype = 'pu', cieobs = data['cri_type']['cieobs']['cct'])
    data['Sr'] = spd_normalize(data['Sr'], norm_type = 'pu', norm_f = Phiv_spd, cieobs = data['cri_type']['cieobs']['cct'])
    
    # Plot test and ref SPDs:
    if axh is None:
        fig, axh = plt.subplots(nrows = 1, ncols = 1)
    axh.plot(data['Sr'][0,:], data['Sr'][1,:],'k-', label = 'Reference')
    axh.plot(data['spd'][0,:], data['spd'][1,:],'r-', label = 'Test')
    axh.set_xlabel('Wavelength (nm)', fontsize = font_size)
    axh.set_ylabel('Radiant power\n(Equal Luminous Flux)', fontsize = font_size)
    axh.set_xlim([360,830]) 
    axh.set_yticklabels([])
    axh.legend(loc = 'upper right', fontsize = font_size)
    
    return axh, data
Esempio n. 11
0
def get_daylightloci_parameters(ccts=None,
                                cieobs=None,
                                wl3=[300, 830, 10],
                                verbosity=0):
    """
    Get parameters for the daylight loci functions xD(1000/CCT) and yD(xD).
    
    Args:
        :ccts:
            | None, optional
            | ndarray with CCTs, if None: ccts = np.arange(4000,25000,250)
        :cieobs:
            | None or list, optional
            | CMF sets to determine parameters for.
            | If None: get for all CMFs sets in _CMF (except scoptopic and deviate observer)
        :wl3:
            | [300,830,10], optional
            | Wavelength range and spacing of daylight phases to be determined
            | from '1931_2'. The default setting results in parameters very close
            | to that in CIE15-2004/2018.
        :verbosity:
            | 0, optional
            | print parameters and make plots.
            
    Returns:
        :dayloci:
            | dict with parameters for each cieobs
    """
    if ccts is None:
        ccts = np.arange(4000, 25000, 250)

    # Get daylight phase spds using cieobs '1931_2':
    # wl3 = [300,830,10] # results in Judd's (1964) coefficients for the function yD(xD)x; other show slight deviations
    for i, cct in enumerate(ccts):
        spd = daylightphase(cct, wl3=wl3, force_daylight_below4000K=False)
        if i == 0:
            spds = spd
        else:
            spds = np.vstack((spds, spd[1:]))

    if verbosity > 0:
        fig, axs = plt.subplots(
            nrows=2, ncols=len(_CMF['types']) -
            2)  # -2: don't include scoptopic and dev observers

    dayloci = {}
    i = 0
    for cieobs in _CMF['types']:
        if 'scotopic' in cieobs:
            continue
        if 'std_dev_obs' in cieobs:
            continue

        # get parameters for cieobs:
        xy, pxy, pxT_l7, pxT_L7, l7, L7 = _get_daylightlocus_parameters(
            ccts, spds, cieobs)
        dayloci[cieobs] = {'pxT_l7k': pxT_l7, 'pxT_L7k': pxT_L7, 'pxy': pxy}

        if verbosity > 0:
            print('\n cieobs:', cieobs)
            print('pxT_l7 (Tcp<=7000K):', pxT_l7)
            print('pxT_L7 (Tcp>7000K):', pxT_L7)
            print('p:xy', pxy)

            axs[0, i].plot(ccts, xy[:, 0], 'r-', label='Data')
            axs[0, i].plot(ccts[l7],
                           np.polyval(pxT_l7, 1000 / ccts[l7]),
                           'b--',
                           label='Fit (Tcp<=7000K)')
            axs[0, i].plot(ccts[L7],
                           np.polyval(pxT_L7, 1000 / ccts[L7]),
                           'c--',
                           label='Fit (Tcp>7000K)')
            axs[0, i].set_title(cieobs)
            axs[0, i].set_xlabel('Tcp (K)')
            axs[0, i].set_ylabel('xD')
            axs[0, i].legend()

            #plotSL(cieobs = cieobs, cspace = 'Yxy', DL = False, axh = axs[1,i])
            axs[1, i].plot(xy[:, 0], xy[:, 1], 'r-', label='Data')
            axs[1, i].plot(xy[:, 0],
                           np.polyval(pxy, xy[:, 0]),
                           'b--',
                           label='Fit')
            # axs[1,i].plot(xy[:,0],np.polyval(pxy_31,xy[:,0]),'g:')
            axs[1, i].set_xlabel('xD')
            axs[1, i].set_ylabel('yD')
            axs[1, i].legend()

        i += 1

    return dayloci