def spectrum_subplot (spectrum): '''Plot a spectrum, with x-axis the wavelength, and y-axis the intensity. The curve is colored at that wavelength by the (approximate) color of a pure spectral color at that wavelength, with intensity constant over wavelength. (This means that dark looking colors here mean that wavelength is poorly viewed by the eye. This is not a complete plotting function, e.g. no file is saved, etc. It is assumed that this function is being called by one that handles those things.''' (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors = numpy.empty ((num_wl, 3)) for i in xrange (0, num_wl): wl_nm = spectrum [i][0] xyz = ciexyz.xyz_from_wavelength (wl_nm) rgb_colors [i] = colormodels.rgb_from_xyz (xyz) # scale to make brightest rgb value = 1.0 rgb_max = numpy.max (rgb_colors) scaling = 1.0 / rgb_max rgb_colors *= scaling # draw color patches (thin vertical lines matching the spectrum curve) in color for i in xrange (0, num_wl-1): # skipping the last one here to stay in range x0 = spectrum [i][0] x1 = spectrum [i+1][0] y0 = spectrum [i][1] y1 = spectrum [i+1][1] poly_x = [x0, x1, x1, x0] poly_y = [0.0, 0.0, y1, y0] color_string = colormodels.irgb_string_from_rgb (rgb_colors [i]) pylab.fill (poly_x, poly_y, color_string, edgecolor=color_string) # plot intensity as a curve pylab.plot ( spectrum [:,0], spectrum [:,1], color='k', linewidth=2.0, antialiased=True)
def test(verbose=0): '''Test the CIE XYZ conversions. Mainly call some functions.''' for i in range(0, 100): wl_nm = 1000.0 * random.random() xyz = ciexyz.xyz_from_wavelength(wl_nm) if verbose >= 1: print('wl_nm = %g, xyz = %s' % (wl_nm, str(xyz))) for i in range(0, 10): empty = ciexyz.empty_spectrum() xyz = ciexyz.xyz_from_spectrum(empty) if verbose >= 1: print('black = %s' % str(xyz)) xyz_555 = ciexyz.xyz_from_wavelength(555.0) if verbose >= 1: print('555 nm = %s' % str(xyz_555)) print('test_ciexyz.test() passed.')
def spectrum_subplot(spectrum): '''Plot a spectrum, with x-axis the wavelength, and y-axis the intensity. The curve is colored at that wavelength by the (approximate) color of a pure spectral color at that wavelength, with intensity constant over wavelength. (This means that dark looking colors here mean that wavelength is poorly viewed by the eye. This is not a complete plotting function, e.g. no file is saved, etc. It is assumed that this function is being called by one that handles those things.''' (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors = numpy.empty((num_wl, 3)) for i in range(0, num_wl): wl_nm = spectrum[i][0] xyz = ciexyz.xyz_from_wavelength(wl_nm) rgb_colors[i] = colormodels.rgb_from_xyz(xyz) # scale to make brightest rgb value = 1.0 rgb_max = numpy.max(rgb_colors) scaling = 1.0 / rgb_max rgb_colors *= scaling # draw color patches (thin vertical lines matching the spectrum curve) in color for i in range(0, num_wl - 1): # skipping the last one here to stay in range x0 = spectrum[i][0] x1 = spectrum[i + 1][0] y0 = spectrum[i][1] y1 = spectrum[i + 1][1] poly_x = [x0, x1, x1, x0] poly_y = [0.0, 0.0, y1, y0] color_string = colormodels.irgb_string_from_rgb(rgb_colors[i]) pylab.fill(poly_x, poly_y, color_string, edgecolor=color_string) # plot intensity as a curve w = spectrum[:, 0] I = spectrum[:, 1] return w, I
def test (verbose=0): '''Test the CIE XYZ conversions. Mainly call some functions.''' for i in xrange (0, 100): wl_nm = 1000.0 * random.random() xyz = ciexyz.xyz_from_wavelength (wl_nm) if verbose >= 1: print 'wl_nm = %g, xyz = %s' % (wl_nm, str (xyz)) for i in xrange (0, 10): empty = ciexyz.empty_spectrum () xyz = ciexyz.xyz_from_spectrum (empty) if verbose >= 1: print 'black = %s' % (str (xyz)) xyz_555 = ciexyz.xyz_from_wavelength (555.0) if verbose >= 1: print '555 nm = %s' % (str (xyz_555)) print 'test_ciexyz.test() passed.'
def test_coverage_1(self, verbose=False): ''' A coverage test. ''' for i in range (100): wl_nm = 1000.0 * random.random() xyz = ciexyz.xyz_from_wavelength (wl_nm) msg = 'wl_nm = %7.3f, xyz = %s' % (wl_nm, str (xyz)) if verbose: print (msg)
def test_coverage_1(self, verbose=False): ''' A coverage test. ''' for i in range(100): wl_nm = 1000.0 * random.random() xyz = ciexyz.xyz_from_wavelength(wl_nm) msg = 'wl_nm = %7.3f, xyz = %s' % (wl_nm, str(xyz)) if verbose: print(msg)
def test_coverage_2(self, verbose=False): ''' Another coverage test. ''' empty = ciexyz.empty_spectrum () xyz = ciexyz.xyz_from_spectrum (empty) if verbose: print ('black = %s' % (str (xyz))) xyz_555 = ciexyz.xyz_from_wavelength (555.0) if verbose: print ('555 nm = %s' % (str (xyz_555)))
def test_coverage_2(self, verbose=False): ''' Another coverage test. ''' empty = ciexyz.empty_spectrum() xyz = ciexyz.xyz_from_spectrum(empty) if verbose: print('black = %s' % (str(xyz))) xyz_555 = ciexyz.xyz_from_wavelength(555.0) if verbose: print('555 nm = %s' % (str(xyz_555)))
def scattered_visual_brightness(): '''Plot the perceptual brightness of Rayleigh scattered light.''' # get 'spectra' for y matching functions and multiply by 1/wl^4 spectrum_y = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum_y.shape for i in range(0, num_wl): wl_nm = spectrum_y[i][0] rayleigh = math.pow(550.0 / wl_nm, 4) xyz = ciexyz.xyz_from_wavelength(wl_nm) spectrum_y[i][1] = xyz[1] * rayleigh pylab.clf() pylab.title('Perceptual Brightness of Rayleigh Scattered Light') pylab.xlabel('Wavelength (nm)') pylab.ylabel('CIE $Y$ / $\lambda^4$') spectrum_subplot(spectrum_y) tighten_x_axis(spectrum_y[:, 0]) # done filename = 'Visual_scattering' print('Saving plot %s' % str(filename)) pylab.savefig(filename)
def scattered_visual_brightness (): '''Plot the perceptual brightness of Rayleigh scattered light.''' # get 'spectra' for y matching functions and multiply by 1/wl^4 spectrum_y = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum_y.shape for i in range (0, num_wl): wl_nm = spectrum_y [i][0] rayleigh = math.pow (550.0 / wl_nm, 4) xyz = ciexyz.xyz_from_wavelength (wl_nm) spectrum_y [i][1] = xyz [1] * rayleigh pylab.clf () pylab.title ('Perceptual Brightness of Rayleigh Scattered Light') pylab.xlabel ('Wavelength (nm)') pylab.ylabel ('CIE $Y$ / $\lambda^4$') spectrum_subplot (spectrum_y) tighten_x_axis (spectrum_y [:,0]) # done filename = 'Visual_scattering' print ('Saving plot %s' % str (filename)) pylab.savefig (filename)
def visible_spectrum_plot(): '''Plot the visible spectrum, as a plot vs wavelength.''' spectrum = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors = numpy.empty((num_wl, 3)) for i in xrange(0, num_wl): xyz = ciexyz.xyz_from_wavelength(spectrum[i][0]) rgb = colormodels.rgb_from_xyz(xyz) rgb_colors[i] = rgb # scale to make brightest rgb value = 1.0 rgb_max = numpy.max(rgb_colors) scaling = 1.0 / rgb_max rgb_colors *= scaling # plot colors and rgb values vs wavelength color_vs_param_plot(spectrum[:, 0], rgb_colors, 'The Visible Spectrum', 'VisibleSpectrum', tight=True, xlabel=r'Wavelength (nm)', ylabel=r'RGB Color')
def visible_spectrum_plot (): '''Plot the visible spectrum, as a plot vs wavelength.''' spectrum = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors = numpy.empty ((num_wl, 3)) for i in xrange (0, num_wl): xyz = ciexyz.xyz_from_wavelength (spectrum [i][0]) rgb = colormodels.rgb_from_xyz (xyz) rgb_colors [i] = rgb # scale to make brightest rgb value = 1.0 rgb_max = numpy.max (rgb_colors) scaling = 1.0 / rgb_max rgb_colors *= scaling # plot colors and rgb values vs wavelength color_vs_param_plot ( spectrum [:,0], rgb_colors, 'The Visible Spectrum', 'VisibleSpectrum', tight = True, xlabel = r'Wavelength (nm)', ylabel = r'RGB Color')
def cie_matching_functions_plot (): '''Plot the CIE XYZ matching functions, as three spectral subplots.''' # get 'spectra' for x,y,z matching functions spectrum_x = ciexyz.empty_spectrum() spectrum_y = ciexyz.empty_spectrum() spectrum_z = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum_x.shape for i in xrange (0, num_wl): wl_nm = spectrum_x [i][0] xyz = ciexyz.xyz_from_wavelength (wl_nm) spectrum_x [i][1] = xyz [0] spectrum_y [i][1] = xyz [1] spectrum_z [i][1] = xyz [2] # Plot three separate subplots, with CIE X in the first, CIE Y in the second, and CIE Z in the third. # Label appropriately for the whole plot. pylab.clf () # X pylab.subplot (3,1,1) pylab.title ('1931 CIE XYZ Matching Functions') pylab.ylabel ('CIE $X$') spectrum_subplot (spectrum_x) tighten_x_axis (spectrum_x [:,0]) # Y pylab.subplot (3,1,2) pylab.ylabel ('CIE $Y$') spectrum_subplot (spectrum_y) tighten_x_axis (spectrum_x [:,0]) # Z pylab.subplot (3,1,3) pylab.xlabel ('Wavelength (nm)') pylab.ylabel ('CIE $Z$') spectrum_subplot (spectrum_z) tighten_x_axis (spectrum_x [:,0]) # done filename = 'CIEXYZ_Matching' print 'Saving plot %s' % str (filename) pylab.savefig (filename)
def cie_matching_functions_plot(): '''Plot the CIE XYZ matching functions, as three spectral subplots.''' # get 'spectra' for x,y,z matching functions spectrum_x = ciexyz.empty_spectrum() spectrum_y = ciexyz.empty_spectrum() spectrum_z = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum_x.shape for i in xrange(0, num_wl): wl_nm = spectrum_x[i][0] xyz = ciexyz.xyz_from_wavelength(wl_nm) spectrum_x[i][1] = xyz[0] spectrum_y[i][1] = xyz[1] spectrum_z[i][1] = xyz[2] # Plot three separate subplots, with CIE X in the first, CIE Y in the second, and CIE Z in the third. # Label appropriately for the whole plot. pylab.clf() # X pylab.subplot(3, 1, 1) pylab.title('1931 CIE XYZ Matching Functions') pylab.ylabel('CIE $X$') spectrum_subplot(spectrum_x) tighten_x_axis(spectrum_x[:, 0]) # Y pylab.subplot(3, 1, 2) pylab.ylabel('CIE $Y$') spectrum_subplot(spectrum_y) tighten_x_axis(spectrum_x[:, 0]) # Z pylab.subplot(3, 1, 3) pylab.xlabel('Wavelength (nm)') pylab.ylabel('CIE $Z$') spectrum_subplot(spectrum_z) tighten_x_axis(spectrum_x[:, 0]) # done filename = 'CIEXYZ_Matching' print 'Saving plot %s' % str(filename) pylab.savefig(filename)
def visible_spectrum_table(filename='visible_spectrum.html'): '''Write an HTML table with the visible spectrum colors.''' spectrum = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors_1 = numpy.empty((num_wl, 3)) rgb_colors_2 = numpy.empty((num_wl, 3)) for i in range(0, num_wl): xyz = ciexyz.xyz_from_wavelength(spectrum[i][0]) rgb_1 = colormodels.rgb_from_xyz(xyz) rgb_2 = colormodels.brightest_rgb_from_xyz(xyz) rgb_colors_1[i] = rgb_1 rgb_colors_2[i] = rgb_2 # scale 1 to make brightest rgb value = 1.0 rgb_max = numpy.max(rgb_colors_1) scaling = 1.0 / rgb_max rgb_colors_1 *= scaling # write HTML file def write_link(f, url, text): '''Write an html link.''' link = '<a href="%s">%s</a><br/>\n' % (url, text) f.write(link) f = open(filename, 'w') # html headers f.write('<html>\n') f.write('<head>\n') f.write('<title>Colors of Pure Spectral Lines</title>\n') f.write('</head>\n') f.write('<body>\n') f.write('<p><h1>Colors of Pure Spectral Lines</h1></p>\n') f.write('<p>%s</p>\n' % 'White added to undisplayable pure colors to fit into rgb space.') f.write('<hr/>\n') # table header f.write('<table border cellpadding="5">\n') f.write('<tr>\n') f.write('<th>Wavelength</th>\n') f.write('<th>R</th>\n') f.write('<th>G</th>\n') f.write('<th>B</th>\n') f.write('<th>Hex Code</th>\n') f.write('<th width=200>Full Brightness</th>\n') f.write('<th width=200>Perceptual Brightness</th>\n') f.write('</tr>\n') # each row for i in range(0, num_wl): irgb_1 = colormodels.irgb_from_rgb(rgb_colors_1[i]) irgb_2 = colormodels.irgb_from_rgb(rgb_colors_2[i]) red = irgb_2[0] green = irgb_2[1] blue = irgb_2[2] hexstr_1 = colormodels.irgb_string_from_irgb(irgb_1) hexstr_2 = colormodels.irgb_string_from_irgb(irgb_2) iwl = spectrum[i][0] code = '%.1f nm' % iwl f.write('<tr>\n') f.write('<td>%s</td>\n' % (code)) f.write('<td>%d</td>\n' % (red)) f.write('<td>%d</td>\n' % (green)) f.write('<td>%d</td>\n' % (blue)) f.write('<td>%s</td>\n' % (hexstr_2)) swatch = " " f.write('<td bgcolor="%s">%s</td>\n' % (hexstr_2, swatch)) f.write('<td bgcolor="%s">%s</td>\n' % (hexstr_1, swatch)) f.write('</tr>\n') f.write('</table>\n') # references f.write('<hr/>\n') f.write('<p>References</p>\n') # one source for data write_link(f, 'http://goffgrafix.com/pantone-rgb-100.php', 'Goffgrafix.com') # another source with basically the same data write_link(f, 'http://www.sandaleo.com/pantone.asp', 'Sandaleo.com') # one with more colors including metallic (also some errors), not quite consistent with the first two write_link( f, 'http://www.loral.org/Z/Colors/100.html', 'Loral.org - Conversions based on CorelDRAW v12 Pantone Solid Coated or Pastel Coated tables and sRGB color space.' ) # some colors for various sports teams write_link( f, 'http://www.pennjersey.info/forums/questions-answers/7895-pantone-colors-colleges-university-mlb-nfl-teams.html', 'Pantone colors for some sports teams.') # some colors for various national flags write_link( f, 'http://desktoppub.about.com/od/colorpalettes/l/aa_flagcolors.htm', 'What color is your flag? Pantone colors for some flags.') write_link(f, 'http://desktoppub.about.com/library/weekly/blcpflagsrwb.htm', 'Red, White, & Blue - Pantone colors for some flags.') write_link( f, 'http://desktoppub.about.com/library/weekly/blcpflagsyellow.htm', 'Yellow or Gold - Pantone colors for some flags.') write_link( f, 'http://desktoppub.about.com/library/weekly/blcpflagsgreen.htm', 'Green - Pantone colors for some flags.') write_link( f, 'http://desktoppub.about.com/library/weekly/blcpatrioticswatches.htm', 'Color swatches - Pantone colors for some flags.') # official Pantone webpages write_link(f, 'http://pantone.com/pages/pantone/Pantone.aspx?pg=19970&ca=25', 'An official PANTONE page') write_link(f, 'http://pantone.com/pages/products/product.aspx?ca=1&pid=293&', 'Another official PANTONE page') # html ending f.write('</body>\n') f.write('</html>\n') f.close()
def visible_spectrum_table (filename='visible_spectrum.html'): '''Write an HTML table with the visible spectrum colors.''' spectrum = ciexyz.empty_spectrum() (num_wl, num_cols) = spectrum.shape # get rgb colors for each wavelength rgb_colors_1 = numpy.empty ((num_wl, 3)) rgb_colors_2 = numpy.empty ((num_wl, 3)) for i in range (0, num_wl): xyz = ciexyz.xyz_from_wavelength (spectrum [i][0]) rgb_1 = colormodels.rgb_from_xyz (xyz) rgb_2 = colormodels.brightest_rgb_from_xyz (xyz) rgb_colors_1 [i] = rgb_1 rgb_colors_2 [i] = rgb_2 # scale 1 to make brightest rgb value = 1.0 rgb_max = numpy.max (rgb_colors_1) scaling = 1.0 / rgb_max rgb_colors_1 *= scaling # write HTML file def write_link (f, url, text): '''Write an html link.''' link = '<a href="%s">%s</a><br/>\n' % (url, text) f.write (link) f = open (filename, 'w') # html headers f.write ('<html>\n') f.write ('<head>\n') f.write ('<title>Colors of Pure Spectral Lines</title>\n') f.write ('</head>\n') f.write ('<body>\n') f.write ('<p><h1>Colors of Pure Spectral Lines</h1></p>\n') f.write ('<p>%s</p>\n' % 'White added to undisplayable pure colors to fit into rgb space.') f.write ('<hr/>\n') # table header f.write ('<table border cellpadding="5">\n') f.write ('<tr>\n') f.write ('<th>Wavelength</th>\n') f.write ('<th>R</th>\n') f.write ('<th>G</th>\n') f.write ('<th>B</th>\n') f.write ('<th>Hex Code</th>\n') f.write ('<th width=200>Full Brightness</th>\n') f.write ('<th width=200>Perceptual Brightness</th>\n') f.write ('</tr>\n') # each row for i in range (0, num_wl): irgb_1 = colormodels.irgb_from_rgb (rgb_colors_1 [i]) irgb_2 = colormodels.irgb_from_rgb (rgb_colors_2 [i]) red = irgb_2 [0] green = irgb_2 [1] blue = irgb_2 [2] hexstr_1 = colormodels.irgb_string_from_irgb (irgb_1) hexstr_2 = colormodels.irgb_string_from_irgb (irgb_2) iwl = spectrum [i][0] code = '%.1f nm' % iwl f.write ('<tr>\n') f.write ('<td>%s</td>\n' % (code)) f.write ('<td>%d</td>\n' % (red)) f.write ('<td>%d</td>\n' % (green)) f.write ('<td>%d</td>\n' % (blue)) f.write ('<td>%s</td>\n' % (hexstr_2)) swatch = " " f.write ('<td bgcolor="%s">%s</td>\n' % (hexstr_2, swatch)) f.write ('<td bgcolor="%s">%s</td>\n' % (hexstr_1, swatch)) f.write ('</tr>\n') f.write ('</table>\n') # references f.write ('<hr/>\n') f.write ('<p>References</p>\n') # one source for data write_link (f, 'http://goffgrafix.com/pantone-rgb-100.php', 'Goffgrafix.com') # another source with basically the same data write_link (f, 'http://www.sandaleo.com/pantone.asp', 'Sandaleo.com') # one with more colors including metallic (also some errors), not quite consistent with the first two write_link (f, 'http://www.loral.org/Z/Colors/100.html', 'Loral.org - Conversions based on CorelDRAW v12 Pantone Solid Coated or Pastel Coated tables and sRGB color space.') # some colors for various sports teams write_link (f, 'http://www.pennjersey.info/forums/questions-answers/7895-pantone-colors-colleges-university-mlb-nfl-teams.html', 'Pantone colors for some sports teams.') # some colors for various national flags write_link (f, 'http://desktoppub.about.com/od/colorpalettes/l/aa_flagcolors.htm', 'What color is your flag? Pantone colors for some flags.') write_link (f, 'http://desktoppub.about.com/library/weekly/blcpflagsrwb.htm', 'Red, White, & Blue - Pantone colors for some flags.') write_link (f, 'http://desktoppub.about.com/library/weekly/blcpflagsyellow.htm', 'Yellow or Gold - Pantone colors for some flags.') write_link (f, 'http://desktoppub.about.com/library/weekly/blcpflagsgreen.htm', 'Green - Pantone colors for some flags.') write_link (f, 'http://desktoppub.about.com/library/weekly/blcpatrioticswatches.htm', 'Color swatches - Pantone colors for some flags.') # official Pantone webpages write_link (f, 'http://pantone.com/pages/pantone/Pantone.aspx?pg=19970&ca=25', 'An official PANTONE page') write_link (f, 'http://pantone.com/pages/products/product.aspx?ca=1&pid=293&', 'Another official PANTONE page') # html ending f.write ('</body>\n') f.write ('</html>\n') f.close()