Ejemplo n.º 1
0
def hsi_to_rgb(hsi,
               spd=None,
               cieobs=_CIEOBS,
               srgb=False,
               linear_rgb=False,
               CSF=None,
               wl=[380, 780, 1]):
    """ 
    Convert HyperSpectral Image to rgb.
    
    Args:
        :hsi:
            | ndarray with hyperspectral image [M,N,L]
        :spd:
            | None, optional
            | ndarray with illumination spectrum
        :cieobs:
            | _CIEOBS, optional
            | CMF set to convert spectral data to xyz tristimulus values.
        :srgb:
            | False, optional
            | If False: Use xyz_to_srgb(spd_to_xyz(...)) to convert to srgb values
            | If True: use camera sensitivity functions.
        :linear_rgb:
            | False, optional
            | If False: use gamma = 2.4 in xyz_to_srgb, if False: use gamma = 1.
        :CSF:
            | None, optional
            | ndarray with camera sensitivity functions 
            | If None: use Nikon D700
        :wl:
            | [380,780,1], optional
            | Wavelength range and spacing or ndarray with wavelengths of HSI image.
    
    Returns:
        :rgb:
            | ndarray with rgb image [M,N,3]
    """
    if spd is None:
        spd = _CIE_E.copy()
    wlr = getwlr(wl)
    spd = cie_interp(spd, wl, kind='linear')

    hsi_2d = np.reshape(hsi, (hsi.shape[0] * hsi.shape[1], hsi.shape[2]))

    if srgb:
        xyz = spd_to_xyz(spd,
                         cieobs=cieobs,
                         relative=True,
                         rfl=np.vstack((wlr, hsi_2d)))
        gamma = 1 if linear_rgb else 2.4
        rgb = xyz_to_srgb(xyz, gamma=gamma) / 255
    else:
        if CSF is None: CSF = _CSF_NIKON_D700
        rgb = rfl_to_rgb(hsi_2d, spd=spd, CSF=CSF, wl=wl)
    return np.reshape(rgb, (hsi.shape[0], hsi.shape[1], 3))
Ejemplo n.º 2
0
def plot_rfl_color_patches(rfl,
                           spd=None,
                           cieobs='1931_2',
                           patch_shape=(100, 100),
                           patch_layout=None,
                           ax=None,
                           show=True):
    """
    Create (and plot) an image with colored patches representing a set of reflectance spectra illuminated by a specified illuminant.
    
    Args:
        :rfl:
            | ndarray with reflectance spectra
        :spd:
            | None, optional
            | ndarray with illuminant spectral power distribution
            | If None: _CIE_D65 is used.
        :cieobs:
            | '1931_2', optional
            | CIE standard observer to use when converting rfl to xyz.
        :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 spd is None:
        spd = _CIE_D65
    xyz = spd_to_xyz(spd, rfl=rfl, cieobs=cieobs)[:, 0, :]
    rgb = xyz_to_srgb(xyz).astype('uint8')
    return plot_rgb_color_patches(rgb,
                                  ax=ax,
                                  patch_shape=patch_shape,
                                  patch_layout=patch_layout,
                                  show=show)
Ejemplo n.º 3
0
    def to_srgb(self, gamma=2.4):
        """
        Calculates IEC:61966 sRGB values from xyz.

        Args:
            :xyz: 
                | ndarray with relative tristimulus values.
            :gamma: 
                | 2.4, optional
                | compression in sRGB

        Returns:
            :rgb: 
                | ndarray with R,G,B values (uint8).
        """
        return LAB(value=xyz_to_srgb(self.value, gamma=gamma),
                   relative=self.relative,
                   cieobs=self.cieobs,
                   dtype='srgb')
Ejemplo n.º 4
0
labw = lx.xyz_to_Vrb_mb(xyzw)
lab = lx.xyz_to_Vrb_mb(xyz)
xyzw_ = lx.Vrb_mb_to_xyz(labw)
xyz_ = lx.Vrb_mb_to_xyz(lab)

labw = lx.xyz_to_Ydlep(xyzw)
lab = lx.xyz_to_Ydlep(xyz)
xyzw_ = lx.Ydlep_to_xyz(labw)
xyz_ = lx.Ydlep_to_xyz(lab)

labw = lx.xyz_to_lms(xyzw)
lab = lx.xyz_to_lms(xyz)
xyzw_ = lx.lms_to_xyz(labw)
xyz_ = lx.lms_to_xyz(lab)

labw = lx.xyz_to_srgb(xyzw)
lab = lx.xyz_to_srgb(xyz)
xyzw_ = lx.srgb_to_xyz(labw)
xyz_ = lx.srgb_to_xyz(lab)

print(labw.shape)
print(lab.shape)
print(xyzw - xyzw_)
print(xyz - xyz_)

# cam_sww6:
xyz, xyzw = lx.spd_to_xyz(spds, rfl=rfls, cieobs='2006_10', out=2)
jabw = lx.xyz_to_lab_cam_sww16(xyzw, xyzw=xyzw.copy())
jab = lx.xyz_to_lab_cam_sww16(xyz, xyzw=xyzw)
xyzw_ = lx.lab_cam_sww16_to_xyz(jabw, xyzw=xyzw)
xyz_ = lx.lab_cam_sww16_to_xyz(jab, xyzw=xyzw)
Ejemplo n.º 5
0
def plot_spectrum_colors(spd = None, spdmax = None,\
                         wavelength_height = -0.05, wavelength_opacity = 1.0, wavelength_lightness = 1.0,\
                         cieobs = _CIEOBS, show = True, axh = None,\
                         show_grid = False,ylabel = 'Spectral intensity (a.u.)',xlim=None,\
                         **kwargs):
    """
    Plot the spectrum colors.
    
    Args:
        :spd:
            | None, optional
            | Spectrum
        :spdmax:
            | None, optional
            | max ylim is set at 1.05 or (1+abs(wavelength_height)*spdmax)
        :wavelength_opacity:
            | 1.0, optional
            | Sets opacity of wavelength rectangle.
        :wavelength_lightness:
            | 1.0, optional
            | Sets lightness of wavelength rectangle.
        :wavelength_height:
            | -0.05 or 'spd', optional
            | Determine wavelength bar height 
            | if not 'spd': x% of spd.max()
        :axh: 
            | None or axes handle, optional
            | Determines axes to plot data in.
            | None: make new figure.
        :show:
            | True or False, optional
            | Invoke matplotlib.pyplot.show() right after plotting
        :cieobs:
            | luxpy._CIEOBS or str, optional
            | Determines CMF set to calculate spectrum locus or other.
        :show_grid:
            | False, optional
            | Show grid (True) or not (False)
        :ylabel:
            | 'Spectral intensity (a.u.)' or str, optional
            | Set y-axis label.
        :xlim:
            | None, optional
            | list or ndarray with xlimits.
        :kwargs: 
            | additional keyword arguments for use with matplotlib.pyplot.
        
    Returns:
        
    """

    if isinstance(cieobs, str):
        cmfs = _CMF[cieobs]['bar']
    else:
        cmfs = cieobs
    cmfs = cmfs[:, cmfs[1:].sum(axis=0) >
                0]  # avoid div by zero in xyz-to-Yxy conversion

    wavs = cmfs[0:1].T
    SL = cmfs[1:4].T

    srgb = xyz_to_srgb(wavelength_lightness * 100 * SL)
    srgb = srgb / srgb.max()

    if show == True:
        if axh is None:
            fig = plt.figure()
            axh = fig.add_subplot(111)

        if (wavelength_height == 'spd') & (spd is not None):
            if spdmax is None:
                spdmax = np.nanmax(spd[1:, :])
            y_min, y_max = 0.0, spdmax * (1.05)
            if xlim is None:
                x_min, x_max = spd[0, :].min(), spd[0, :].max()
            else:
                x_min, x_max = xlim

            SLrect = np.vstack([
                (x_min, 0.0),
                spd.T,
                (x_max, 0.0),
            ])
            wavelength_height = y_max
            spdmax = 1
        else:
            if (spdmax is None) & (spd is not None):
                spdmax = np.nanmax(spd[1:, :])
                y_min, y_max = wavelength_height * spdmax, spdmax * (
                    1 + np.abs(wavelength_height))

            elif (spdmax is None) & (spd is None):
                spdmax = 1
                y_min, y_max = wavelength_height, 0

            elif (spdmax is not None):
                y_min, y_max = wavelength_height * spdmax, spdmax  #*(1 + np.abs(wavelength_height))

            if xlim is None:
                x_min, x_max = wavs.min(), wavs.max()
            else:
                x_min, x_max = xlim

            SLrect = np.vstack([
                (x_min, 0.0),
                (x_min, wavelength_height * spdmax),
                (x_max, wavelength_height * spdmax),
                (x_max, 0.0),
            ])

        axh.set_xlim([x_min, x_max])
        axh.set_ylim([y_min, y_max])

        polygon = Polygon(SLrect, facecolor=None, edgecolor=None)
        axh.add_patch(polygon)
        padding = 0.1
        axh.bar(x=wavs - padding,
                height=wavelength_height * spdmax,
                width=1 + padding,
                color=srgb,
                align='edge',
                linewidth=0,
                clip_path=polygon)

        if spd is not None:
            axh.plot(spd[0:1, :].T, spd[1:, :].T, color='k', label='spd')

        if show_grid == True:
            plt.grid(True)
        axh.set_xlabel('Wavelength (nm)', kwargs)
        axh.set_ylabel(ylabel, kwargs)

        #plt.show()

        return axh
    else:
        return None
Ejemplo n.º 6
0
def plot_chromaticity_diagram_colors(diagram_samples = 256, diagram_opacity = 1.0, diagram_lightness = 0.25,\
                                      cieobs = _CIEOBS, cspace = 'Yxy', cspace_pars = {},\
                                      show = True, axh = None,\
                                      show_grid = False, label_fontname = 'Times New Roman', label_fontsize = 12,\
                                      **kwargs):
    """
    Plot the chromaticity diagram colors.
    
    Args:
        :diagram_samples:
            | 256, optional
            | Sampling resolution of color space.
        :diagram_opacity:
            | 1.0, optional
            | Sets opacity of chromaticity diagram
        :diagram_lightness:
            | 0.25, optional
            | Sets lightness of chromaticity diagram
        :axh: 
            | None or axes handle, optional
            | Determines axes to plot data in.
            | None: make new figure.
        :show:
            | True or False, optional
            | Invoke matplotlib.pyplot.show() right after plotting
        :cieobs:
            | luxpy._CIEOBS or str, optional
            | Determines CMF set to calculate spectrum locus or other.
        :cspace:
            | luxpy._CSPACE or str, optional
            | Determines color space / chromaticity diagram to plot data in.
            | Note that data is expected to be in specified :cspace:
        :cspace_pars:
            | {} or dict, optional
            | Dict with parameters required by color space specified in :cspace: 
            | (for use with luxpy.colortf())
        :show_grid:
            | False, optional
            | Show grid (True) or not (False)
        :label_fontname: 
            | 'Times New Roman', optional
            | Sets font type of axis labels.
        :label_fontsize:
            | 12, optional
            | Sets font size of axis labels.
        :kwargs: 
            | additional keyword arguments for use with matplotlib.pyplot.
        
    Returns:
        
    """

    if isinstance(cieobs, str):
        SL = _CMF[cieobs]['bar'][1:4].T
    else:
        SL = cieobs[1:4].T
    SL = 100.0 * SL / (SL[:, 1, None] + _EPS)
    SL = SL[SL.sum(axis=1) >
            0, :]  # avoid div by zero in xyz-to-Yxy conversion
    SL = colortf(SL, tf=cspace, tfa0=cspace_pars)
    plambdamax = SL[:, 1].argmax()
    SL = np.vstack(
        (SL[:(plambdamax + 1), :], SL[0])
    )  # add lowest wavelength data and go to max of gamut in x (there is a reversal for some cmf set wavelengths >~700 nm!)
    Y, x, y = asplit(SL)
    SL = np.vstack((x, y)).T

    # create grid for conversion to srgb
    offset = _EPS
    min_x = min(offset, x.min())
    max_x = max(1, x.max())
    min_y = min(offset, y.min())
    max_y = max(1, y.max())
    ii, jj = np.meshgrid(
        np.linspace(min_x - offset, max_x + offset, int(diagram_samples)),
        np.linspace(max_y + offset, min_y - offset, int(diagram_samples)))
    ij = np.dstack((ii, jj))
    ij[ij == 0] = offset

    ij2D = ij.reshape((diagram_samples**2, 2))
    ij2D = np.hstack((diagram_lightness * 100 * np.ones(
        (ij2D.shape[0], 1)), ij2D))
    xyz = colortf(ij2D, tf=cspace + '>xyz', tfa0=cspace_pars)

    xyz[xyz < 0] = 0
    xyz[np.isinf(xyz.sum(axis=1)), :] = np.nan
    xyz[np.isnan(xyz.sum(axis=1)), :] = offset

    srgb = xyz_to_srgb(xyz)
    srgb = srgb / srgb.max()
    srgb = srgb.reshape((diagram_samples, diagram_samples, 3))

    if show == True:
        if axh is None:
            fig = plt.figure()
            axh = fig.add_subplot(111)
        polygon = Polygon(SL, facecolor='none', edgecolor='none')
        axh.add_patch(polygon)
        image = axh.imshow(srgb,
                           interpolation='bilinear',
                           extent=(min_x, max_x, min_y - 0.05, max_y),
                           clip_path=None,
                           alpha=diagram_opacity)
        image.set_clip_path(polygon)
        axh.plot(x, y, color='darkgray')
        if (cspace == 'Yxy') & (isinstance(cieobs, str)):
            axh.set_xlim([0, 1])
            axh.set_ylim([0, 1])
        elif (cspace == 'Yuv') & (isinstance(cieobs, str)):
            axh.set_xlim([0, 0.6])
            axh.set_ylim([0, 0.6])
        if (cspace is not None):
            xlabel = _CSPACE_AXES[cspace][1]
            ylabel = _CSPACE_AXES[cspace][2]
            if (label_fontname is not None) & (label_fontsize is not None):
                axh.set_xlabel(xlabel,
                               fontname=label_fontname,
                               fontsize=label_fontsize)
                axh.set_ylabel(ylabel,
                               fontname=label_fontname,
                               fontsize=label_fontsize)

        if show_grid == True:
            axh.grid(True)
        #plt.show()

        return axh
    else:
        return None
Ejemplo n.º 7
0
 def test_srgb(self, getvars):
     S, spds, rfls, xyz, xyzw = getvars
     lab = lx.xyz_to_srgb(
         xyz[1:, :])  # first xyz row out of srgb gamut, so non-reversible!
     xyz_ = lx.srgb_to_xyz(lab)
     assert np.isclose(xyz[1:, :], xyz_).all()
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def _get_hue_map(hbins = 16, start_hue = 0.0, 
                 hbinnrs = None, xyzri = None, xyzrw = None, cri_type = None):
    """
    Generate color map for hue bins.
    
    Args:
        :hbins:
            | 16 or ndarray with sorted hue bin centers (°), optional
        :start_hue:
            | 0.0, optional
        :hbinnrs: 
            | None, optional
            | ndarray with hue bin number of each sample.
            | If hbinnrs, xyzri, xyzrw and cri_type are all not-None: 
            |    use these to calculate color map, otherwise just use number of
            |    hue bins :hbins: and :start_hue:
        :xyzri:
            | None, optional
            | relative xyz tristimulus values of samples under ref. illuminant.
            | see :hbinnrs: for more info when this is used.
        :xyzrw:
            | None, optional
            | relative xyz tristimulus values of ref. illuminant white point.
            | see :hbinnrs: for more info when this is used.
        :cri_type:
            | None, optional
            | Specifies dict with default cri model parameters 
            | (needed to get correct :cieobs:) 
            | see :hbinnrs: for more info when this is used.
    
    Returns:
        :cmap:
            | list with rgb values (one for each hue bin) for plotting.
    """
    # Setup hbincenters and hsv_hues:
    if isinstance(hbins,float) | isinstance(hbins,int):
        nhbins = hbins
        dhbins = 360/(nhbins) # hue bin width
        hbincenters = np.arange(start_hue + dhbins/2, 360, dhbins)
        hbincenters = np.sort(hbincenters)
    else:
        hbincenters = hbins
        idx = np.argsort(hbincenters)
        hbincenters = hbincenters[idx]
        nhbins = hbincenters.shape[0]
    
    cmap = []
    if (hbinnrs is not None) & (xyzri is not None) & (xyzrw is not None) & (cri_type is not None):
        xyzw = spd_to_xyz(_CIE_D65, relative = True, cieobs = cri_type['cieobs']['xyz'])
        xyzri = cat.apply(xyzri[:,0,:],xyzw1 = xyzrw, xyzw2 = xyzw)
                
        # Create color from xyz average:
        for i in range(nhbins):
            xyzrhi = xyzri[hbinnrs[:,0] == i,:].mean(axis=0,keepdims=True)
            rgbrhi = xyz_to_srgb(xyzrhi)/255
            cmap.append(rgbrhi)
    else:
        # Create color from hue angle:
            
        # Setup color for plotting hue bins:
        hbincenters = hbincenters*np.pi/180
        hsv_hues = hbincenters - 30*np.pi/180
        hsv_hues = hsv_hues/hsv_hues.max()
            
        for i in range(nhbins):   
            #c = np.abs(np.array(colorsys.hsv_to_rgb(hsv_hues[i], 0.75, 0.85)))
            c = np.abs(np.array(colorsys.hls_to_rgb(hsv_hues[i], 0.45, 0.5)))
            cmap.append(c)
    
    return cmap
Ejemplo n.º 10
0
def plot_chromaticity_diagram_colors(diagram_samples = 256, diagram_opacity = 1.0, diagram_lightness = 0.25,\
                                      cieobs = _CIEOBS, cspace = 'Yxy', cspace_pars = {},\
                                      show = True, axh = None,\
                                      show_grid = True, label_fontname = 'Times New Roman', label_fontsize = 12,\
                                      **kwargs):
    """
    Plot the chromaticity diagram colors.
    
    Args:
        :diagram_samples:
            | 256, optional
            | Sampling resolution of color space.
        :diagram_opacity:
            | 1.0, optional
            | Sets opacity of chromaticity diagram
        :diagram_lightness:
            | 0.25, optional
            | Sets lightness of chromaticity diagram
        :axh: 
            | None or axes handle, optional
            | Determines axes to plot data in.
            | None: make new figure.
        :show:
            | True or False, optional
            | Invoke matplotlib.pyplot.show() right after plotting
        :cieobs:
            | luxpy._CIEOBS or str, optional
            | Determines CMF set to calculate spectrum locus or other.
        :cspace:
            | luxpy._CSPACE or str, optional
            | Determines color space / chromaticity diagram to plot data in.
            | Note that data is expected to be in specified :cspace:
        :cspace_pars:
            | {} or dict, optional
            | Dict with parameters required by color space specified in :cspace: 
            | (for use with luxpy.colortf())
        :show_grid:
            | True, optional
            | Show grid (True) or not (False)
        :label_fontname: 
            | 'Times New Roman', optional
            | Sets font type of axis labels.
        :label_fontsize:
            | 12, optional
            | Sets font size of axis labels.
        :kwargs: 
            | additional keyword arguments for use with matplotlib.pyplot.
        
    Returns:
        
    """
    offset = _EPS
    ii, jj = np.meshgrid(np.linspace(offset, 1 + offset, diagram_samples), np.linspace(1+offset, offset, diagram_samples))
    ij = np.dstack((ii, jj))
    
    SL =  _CMF[cieobs]['bar'][1:4].T
    SL = np.vstack((SL,SL[0]))
    SL = 100.0*SL/SL[:,1,None]
    SL = colortf(SL, tf = cspace, tfa0 = cspace_pars)
    Y,x,y = asplit(SL)
    SL = np.vstack((x,y)).T

    
    ij2D = ij.reshape((diagram_samples**2,2))
    ij2D = np.hstack((diagram_lightness*100*np.ones((ij2D.shape[0],1)), ij2D))
    xyz = colortf(ij2D, tf = cspace + '>xyz', tfa0 = cspace_pars)

    xyz[xyz < 0] = 0
    xyz[np.isinf(xyz.sum(axis=1)),:] = np.nan
    xyz[np.isnan(xyz.sum(axis=1)),:] = offset
    
    srgb = xyz_to_srgb(xyz)
    srgb = srgb/srgb.max()
    srgb = srgb.reshape((diagram_samples,diagram_samples,3))

    if show == True:
        if axh is None:
            fig = plt.figure()
            axh = fig.add_subplot(111)
        polygon = Polygon(SL, facecolor='none', edgecolor='none')
        axh.add_patch(polygon)
        image = axh.imshow(
            srgb,
            interpolation='bilinear',
            extent = (0.0, 1, -0.05, 1),
            clip_path=None,
            alpha=diagram_opacity)
        image.set_clip_path(polygon)
        plt.plot(x,y, color = 'darkgray')
        if cspace == 'Yxy':
            plt.xlim([0,1])
            plt.ylim([0,1])
        elif cspace == 'Yuv':
            plt.xlim([0,0.6])
            plt.ylim([0,0.6])
        if (cspace is not None):
            xlabel = _CSPACE_AXES[cspace][1]
            ylabel = _CSPACE_AXES[cspace][2]
            if (label_fontname is not None) & (label_fontsize is not None):
                plt.xlabel(xlabel, fontname = label_fontname, fontsize = label_fontsize)
                plt.ylabel(ylabel, fontname = label_fontname, fontsize = label_fontsize)
                
        if show_grid == True:
            plt.grid()
        #plt.show()
    
        return axh
    else:
        return None