Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@nbremer
Last active June 11, 2016 17:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nbremer/4b42493b70dbc9e1ce02 to your computer and use it in GitHub Desktop.
Save nbremer/4b42493b70dbc9e1ce02 to your computer and use it in GitHub Desktop.
A SOM Clustering of block Colors - Including RGB
height: 800

All of the custom colors found in d3.js blocks were used as input. The data was taken from enjalot's block and includes 3250 different blocks. He parsed out hex codes, hsl(a) and rgb(a) in any html, js or coffee file found in each block and I converted all of these to 6-digit hex codes. There were 24700 different color statements in these blocks that make up 4350 unique colors. The Self Organizing Map clustering grouped similar colors together in hexagons and displays the "average" rgb value. The size of each hexagon is scaled to the number of (the 24700) colors that are present in each hexagon. The biggest one, pure black, #000000, has 1500 entries

Another version, based on a clustering of both the rgb & hsl values can be found here

A collection of blocks scanned with blockscanner for the bl.ocksplorer.org project with some further processing. Based on enjalot's block: block colors

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Block Color Clustering</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
<script type="text/javascript" src="http://d3js.org/d3.hexbin.v0.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.js"></script>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:700,400,300' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Lora' rel='stylesheet' type='text/css'>
<style>
body {
text-align: center;
}
.header {
font-family: 'Montserrat', sans-serif;
margin-top: 20px;
margin-left: 40px;
padding-bottom: 20px;
font-size: 34px;
text-align: left;
max-width: 900px;
color: #525252;
}
.hint {
font-family: 'Lora', serif;
margin-top: 10px;
color: #AAAAAA;
font-size: 12px;
max-width: 750px;
}
.popover{
font-family: 'Montserrat', sans-serif;
font-size: 12px;
font-weight: 400;
color: #525252;
text-align: center;
}
</style>
</head>
<body>
<div class="header">
A Self Organizing Map Clustering of block Colors
<div class="hint">
<p>All of the custom colors found in d3.js blocks were used as input. The data was taken from the <a href="http://bl.ocks.org/enjalot/de262983e3ba0c0f89c1">enjalot's block</a> and includes 3250 different blocks.
He parsed out hex codes, hsl(a) and rgb(a) in any html, js or coffee file found in each block and I converted all of these to 6-digit hex codes. There were 24700 different color statements in these blocks that make up 4350 unique colors.</p>
<p>The clustering grouped similar colors together in 600 hexagons (based on their RGB values, thus 3 variables in total). The map below displays the "average" hex value and the size of each hexagon is scaled to the number of (the 24700) colors that are grouped in each hexagon.
The biggest one, pure black, #000000, has 1500 entries. In essence it is an exercise in trying to map a 3D color space into a 2D plane while also looking at the nuances in colors used in blocks :)</p>
</div>
</div>
<div id="chart"></div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
///////////////////////////////////////////////////////////////////////////
/////////////////////////////// SOM Data //////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//The color of each hexagon
var color = ["#FFFFFF", "#FDFDFE", "#FFF8FA", "#FEFCEF", "#FEF5ED", "#FFFEE1", "#FFFFD6", "#FCF1CB", "#F7E1CF", "#FCDAC7", "#FDC2C7", "#FDB5BE", "#FBB4A7", "#FCAD91", "#FE9796", "#EB8B7D", "#FB7A6E", "#FC8655", "#FC8D3B", "#F47924", "#FE7E0E", "#FF7D00", "#EE6C13", "#F06300", "#D85F05", "#D44603", "#F45200", "#FA4200", "#FB2E00", "#FE0000", "#FBFCFC", "#FBFBF9", "#FEF8F4", "#FEEFF3", "#FCF5E5", "#FAF6DB", "#FAFAD2", "#FEE9CD", "#FCE6C5", "#F9DBB5", "#FCCCAD", "#EEB998", "#DFBB83", "#F1A483", "#FFA07A", "#FD946B", "#F88A62", "#ED8F4C", "#FC9B2A", "#F98F1B", "#FE8E00", "#EF7F08", "#E77600", "#DA6B06", "#B85A0D", "#E5540D", "#FB5519", "#EF3B1F", "#FD1509", "#E10507", "#F2FFFC", "#F7FAFE", "#F7F8F7", "#F2FDEF", "#F9EFE6", "#FDEDDF", "#FCEDD6", "#FEFCCC", "#FEF5BC", "#FEE3B5", "#FEDCAA", "#FDD1A0", "#E6C893", "#FDBD84", "#FDBC75", "#FDAD6A", "#F4A360", "#FCB24C", "#F2A541", "#FBBD07", "#FFA600", "#F5A30A", "#DF8800", "#DD8213", "#CF6823", "#E65D28", "#EF5934", "#FB4C2C", "#FE2223", "#FC034C", "#EFF8FD", "#F5F4F5", "#F1F1F1", "#EDF8E8", "#FDDCEE", "#FEE3DF", "#FCF2D0", "#FFFFBF", "#FFFEB2", "#FEEEA6", "#FDE190", "#FEDD8B", "#FBCB8B", "#FDD975", "#FEC960", "#FDB161", "#FEC34F", "#FDBF31", "#FDD832", "#FED400", "#E5AE04", "#D29A00", "#B98309", "#CF8425", "#E0763C", "#F76846", "#F94945", "#EE3529", "#D51147", "#E41A1C", "#DFFEFF", "#EEF2FD", "#F1EEF6", "#EDEEEE", "#EBE4F1", "#F9CAE5", "#F0D8DD", "#F3EEC5", "#F7FBB8", "#EDF8AF", "#FFFE98", "#F0E58C", "#FFE97E", "#FEED69", "#FCDA5D", "#EACE64", "#E8BD50", "#F0EC38", "#FFFD32", "#FDFD00", "#EFDD00", "#C4AD00", "#D8A621", "#BC802C", "#CE7D3E", "#D7634E", "#E25552", "#DD4734", "#D72C26", "#D51918", "#E1F4F8", "#E4E4FA", "#E9EAEA", "#E2F3DC", "#E0E0E0", "#E6DFD4", "#E6F4D0", "#E6F4C8", "#DCEBBB", "#EDE7AB", "#E4F699", "#D9EF8B", "#F2FE63", "#CBE564", "#DFCF79", "#D8AF67", "#C8C140", "#ADFE2F", "#DDE627", "#C0FF00", "#B4BF00", "#BDBF22", "#BB9E38", "#B08B4E", "#BE7B64", "#D25F64", "#D23E55", "#CB303F", "#CA191D", "#BA0000", "#DAECFE", "#DEEBF5", "#E6E0EF", "#E6E6E6", "#E2E2E3", "#DDDDDC", "#DFE1CB", "#D7F1D3", "#CDEAC5", "#C7E9B4", "#D8F2A2", "#D4DA93", "#CDE984", "#D0FE63", "#B3DE69", "#B4CE6A", "#BDB46B", "#A7D751", "#9ACA32", "#8AE40B", "#91D900", "#A3CC00", "#9D9D04", "#A56F1C", "#A07440", "#9E615D", "#AE494A", "#BD3A27", "#B21E27", "#C30023", "#C1E6FF", "#D2E4F0", "#D9D9EA", "#E6D3E7", "#DBDBDB", "#D8D8D8", "#D0D0D0", "#C4D5CF", "#C6E9C0", "#B9E4B7", "#BCDFAA", "#C2E599", "#BFE47B", "#B1FF62", "#A2D76B", "#A0BD66", "#8D9F55", "#7DBB43", "#85EC2D", "#7DFD00", "#7DE400", "#81B402", "#808000", "#8B6B31", "#7A563C", "#8C554B", "#A4542A", "#A32E28", "#A80321", "#960145", "#ACF1F3", "#CAEBE5", "#C6DAEF", "#CED2E6", "#DECBE2", "#CADDDA", "#CFCECE", "#CBCBCC", "#C6C6C6", "#B5C7B0", "#A4DBB4", "#A9DAA2", "#B3DD8A", "#9FEA87", "#93FF63", "#8ECA5F", "#7EC37D", "#6B9973", "#74CC32", "#52F400", "#69ED00", "#62B107", "#6C9A22", "#64740C", "#627A3A", "#776752", "#863A3A", "#853B20", "#9F3302", "#810426", "#B0E0E4", "#BAE6EF", "#BDD5E6", "#C3C9E1", "#CCD1D9", "#D4D3D1", "#D6D1C6", "#CCCBBA", "#BCBCBC", "#B6B6B6", "#9BB7B7", "#9FD899", "#96DD8A", "#93F494", "#6CFE64", "#66D161", "#73C376", "#63B962", "#3DE934", "#3AF900", "#45D40C", "#4DAC26", "#4D9022", "#58692F", "#554C40", "#535454", "#7F601B", "#88460D", "#8B231E", "#9C0003", "#9DE2C9", "#AEDED5", "#ACD8E7", "#B9B9FF", "#C6C0DC", "#E5C9CB", "#E2D8BF", "#D8CAAA", "#C6BDAB", "#B2B2B3", "#A9A9A9", "#ABAF9E", "#92BB8D", "#84D4A3", "#77DF94", "#60FE7B", "#6CE075", "#4ECD87", "#2FFA3B", "#00FC00", "#26C90E", "#4AA02E", "#2E9F2B", "#1E8D1E", "#386A2D", "#416156", "#494A4D", "#51510E", "#862903", "#840000", "#81FED5", "#9DD9E7", "#AFC6E3", "#BCBBDB", "#D6BAD8", "#F4B5D5", "#D6A9B5", "#D1B48A", "#BAAD9B", "#A0A1A1", "#9AAAB3", "#8DAA98", "#76C3AE", "#82CEC2", "#6EE3BA", "#62FEA2", "#1CF887", "#00FC8B", "#08DC51", "#32CC33", "#4FAB4A", "#418743", "#00B300", "#028400", "#266914", "#314E52", "#444444", "#524028", "#6B220B", "#660010", "#61F6FA", "#81D1EC", "#9FCAE1", "#B0C5CE", "#C6B0D5", "#E9A4C9", "#FB9DBA", "#E7959B", "#C79A95", "#B09997", "#989999", "#959595", "#8A88A6", "#7BA3B6", "#65C6A6", "#63FFCC", "#2DE9C3", "#00FFBB", "#0DCA75", "#3EAF73", "#43AA5E", "#2FA457", "#1F8B43", "#008E38", "#016302", "#155120", "#2F3A48", "#3D3E3E", "#57162D", "#542F05", "#8ACAFB", "#91C2DC", "#A3BBD2", "#BEA9D0", "#DD9ED9", "#E78AC2", "#DC77AC", "#D77780", "#BC8D8E", "#A6967C", "#87A17C", "#878787", "#789199", "#5BB2AD", "#52CFCC", "#3EDED1", "#00FEFD", "#00CCD0", "#20B1A9", "#448571", "#0DB54F", "#239254", "#197639", "#006A31", "#004510", "#153617", "#373536", "#323232", "#442728", "#39250F", "#5FC1F2", "#85B5E8", "#91B5CD", "#AFABD4", "#C694C8", "#EF81EF", "#F781BF", "#D96F93", "#BD6682", "#A37380", "#888565", "#7F7F7F", "#6F838F", "#5F9B9E", "#43A4A0", "#3FB6C0", "#35A6FA", "#01C1FF", "#17BECF", "#2B9295", "#189F76", "#019268", "#2B7B6F", "#016557", "#00592B", "#00412F", "#0D3031", "#2B2842", "#2B2C2D", "#252525", "#6BAED6", "#7FB1D3", "#9BA0C6", "#9C99E3", "#D86DD9", "#E377C2", "#FE68B5", "#B460A5", "#956AA9", "#7B6786", "#777777", "#677886", "#667997", "#6795B7", "#47ACD1", "#289DD6", "#1492FC", "#00AAE4", "#00A5AD", "#008A8D", "#00807B", "#226A8B", "#03507A", "#174759", "#013B5B", "#032F46", "#172944", "#212C30", "#212122", "#2A1F15", "#63A3CD", "#74ABD0", "#8C9AC8", "#A48DC2", "#BB7EBC", "#D569B6", "#F8639E", "#DC457D", "#9E519B", "#85559E", "#727271", "#727866", "#666699", "#776DB1", "#587CBB", "#4391C5", "#387EFA", "#0269FD", "#0296CC", "#037FB0", "#05739C", "#03598A", "#25577C", "#07407F", "#09306B", "#06305F", "#081E57", "#0B0E39", "#11202B", "#1A1A1A", "#6488D2", "#817DBB", "#9570DA", "#9664BD", "#BA54D4", "#C93EA4", "#E92D90", "#A54778", "#893E9F", "#7A4073", "#656565", "#5F697E", "#6C56A3", "#5D61AB", "#4682B3", "#427BC2", "#3E67DD", "#1F8AC5", "#026DCC", "#056CAE", "#025C9F", "#074E9A", "#2B3696", "#092B8C", "#02287C", "#181A6F", "#03055F", "#070524", "#0E131E", "#111110", "#6299F6", "#6B6ECC", "#6957CC", "#9933CB", "#BC18C7", "#EB26D3", "#E11E70", "#C81884", "#942563", "#782E8B", "#6A4767", "#50566B", "#663E99", "#6B5092", "#5268AF", "#4171B2", "#3283BD", "#2A80B9", "#1E77B3", "#186BB1", "#0548CF", "#0A3DB3", "#2C2CD1", "#0D1B98", "#010086", "#15117F", "#3C1865", "#2B034B", "#350409", "#06060B", "#706EF6", "#4E41FA", "#8E2BE6", "#9300D8", "#FE01FE", "#FE1196", "#F30183", "#B00178", "#860286", "#72026E", "#383A76", "#4F308A", "#4D518D", "#5553A3", "#376698", "#387FB4", "#308FBD", "#2C7AB4", "#216FB6", "#2262AA", "#052AF7", "#0200FE", "#0100CD", "#0301B6", "#3410A0", "#460481", "#490068", "#470149", "#130000", "#000000"];
var counts = [1410, 8, 41, 61, 68, 49, 30, 7, 28, 19, 39, 40, 30, 14, 43, 58, 79, 63, 69, 13, 53, 39, 29, 65, 49, 62, 37, 63, 33, 194, 38, 141, 21, 35, 29, 69, 25, 40, 56, 56, 18, 7, 40, 29, 25, 25, 37, 13, 30, 10, 67, 2, 52, 1, 29, 42, 4, 23, 15, 18, 51, 74, 90, 38, 26, 33, 69, 60, 23, 38, 42, 59, 44, 55, 48, 37, 29, 35, 41, 11, 37, 6, 52, 19, 39, 9, 11, 27, 19, 25, 47, 71, 78, 27, 26, 62, 1, 47, 48, 37, 33, 35, 19, 29, 35, 81, 24, 18, 24, 49, 36, 52, 33, 17, 7, 94, 26, 29, 56, 72, 26, 28, 63, 213, 29, 33, 8, 4, 19, 26, 34, 26, 2, 37, 29, 14, 49, 13, 23, 54, 3, 63, 33, 18, 49, 31, 19, 35, 111, 34, 38, 29, 15, 32, 33, 7, 17, 11, 22, 32, 27, 20, 28, 11, 7, 15, 7, 26, 2, 4, 53, 43, 38, 11, 16, 64, 33, 18, 20, 74, 19, 58, 14, 64, 28, 197, 23, 15, 28, 19, 21, 56, 10, 32, 25, 28, 36, 26, 37, 1, 52, 52, 7, 39, 13, 56, 42, 21, 60, 38, 29, 24, 55, 14, 35, 77, 21, 8, 38, 37, 3, 14, 8, 20, 42, 7, 44, 41, 3, 51, 52, 17, 26, 32, 13, 38, 61, 58, 68, 67, 37, 31, 90, 29, 18, 9, 7, 455, 54, 5, 27, 43, 55, 1, 14, 23, 32, 6, 4, 41, 48, 19, 67, 6, 35, 24, 40, 3, 41, 31, 42, 5, 35, 25, 1, 42, 2, 7, 186, 23, 8, 52, 38, 56, 42, 8, 68, 62, 3, 24, 2, 12, 19, 36, 9, 127, 13, 52, 19, 48, 33, 38, 50, 14, 1, 7, 14, 37, 7, 33, 230, 15, 36, 1, 5, 23, 1, 5, 6, 70, 9, 2, 61, 38, 9, 14, 38, 7, 29, 99, 30, 40, 70, 66, 60, 47, 6, 35, 15, 19, 14, 4, 7, 79, 2, 28, 3, 60, 6, 34, 38, 15, 27, 56, 20, 38, 116, 8, 24, 42, 61, 40, 98, 11, 48, 14, 17, 32, 48, 14, 209, 62, 27, 11, 65, 28, 2, 3, 14, 44, 18, 72, 51, 19, 49, 9, 22, 44, 13, 17, 45, 39, 55, 39, 57, 18, 23, 13, 30, 26, 8, 97, 44, 16, 41, 30, 52, 36, 31, 18, 9, 62, 19, 53, 28, 9, 11, 293, 1, 8, 54, 8, 8, 19, 23, 32, 17, 31, 16, 8, 7, 81, 33, 35, 22, 34, 11, 34, 35, 38, 44, 16, 9, 51, 25, 40, 3, 10, 16, 45, 82, 29, 65, 42, 34, 37, 33, 28, 47, 32, 295, 17, 9, 16, 47, 34, 49, 36, 18, 57, 47, 23, 25, 9, 29, 7, 18, 4, 261, 6, 36, 39, 30, 23, 36, 54, 27, 13, 72, 47, 47, 13, 1, 91, 14, 63, 7, 14, 38, 40, 8, 29, 16, 26, 48, 18, 26, 21, 9, 37, 15, 20, 34, 53, 32, 7, 59, 19, 16, 34, 257, 11, 34, 20, 44, 10, 37, 30, 11, 56, 34, 62, 46, 35, 12, 30, 9, 13, 18, 90, 56, 37, 27, 30, 10, 5, 33, 70, 21, 26, 38, 28, 32, 36, 38, 43, 89, 33, 86, 1, 13, 10, 3, 6, 79, 6, 6, 15, 13, 39, 57, 15, 31, 34, 48, 31, 39, 15, 89, 33, 41, 58, 21, 60, 50, 36, 43, 27, 45, 47, 12, 93, 45, 9, 6, 54, 14, 31, 7, 1500];
//svg sizes and margins
var margin = {left: 50, top: 50, right: 0, bottom: -30},
width = 920,
height = 550;
//The number of columns and rows of the heatmap
var MapColumns = 30,
MapRows = 20;
///////////////////////////////////////////////////////////////////////////
/////////////////////// Create hexagon variables //////////////////////////
///////////////////////////////////////////////////////////////////////////
//The maximum radius the hexagons can have to still fit the screen
var hexRadius = d3.min([width/(Math.sqrt(3)*(MapColumns+3)),
height/((MapRows+3)*1.5)]);
//Set the new height and width based on the max possible
//width = MapColumns*hexRadius*Math.sqrt(3);
//heigth = MapRows*1.5*hexRadius;//+0.5*hexRadius;
//Scale for the min and max hex sizes, based on circular sqrt
var hexSize = d3.scale.sqrt()
.range([hexRadius*0.3,hexRadius*3])
.domain([d3.min(counts), d3.max(counts)]);
//Initiate hexbin
var hexbin = d3.hexbin()
.radius(hexRadius)
.size([width, height])
.x(function(d) { return d.xPos; })
.y(function(d) { return d.yPos; });
//Calculate the center positions of each hexagon
var points = [],
counter = 0;
for (var i = 0; i < MapRows; i++) {
for (var j = 0; j < MapColumns; j++) {
points[counter] = {
xPos: hexRadius * j * 1.75,
yPos: hexRadius * i * 1.5,
color: color[counter],
counts: counts[counter]
}
counter = counter + 1;
}//for j
}//for i
///////////////////////////////////////////////////////////////////////////
////////////////////////////// Initiate SVG ///////////////////////////////
///////////////////////////////////////////////////////////////////////////
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
///////////////////////////////////////////////////////////////////////////
////////////////////// Draw hexagons and color them ///////////////////////
///////////////////////////////////////////////////////////////////////////
//Create the hexbin data
var hexData = hexbin(points);
//Add extra data to the hexbin result
hexData.forEach(function(d,i) {
d.color = points[i].color;
d.counts = points[i].counts;
});
//Sort from biggest to smallest hexbin
hexData.sort(function(a, b) { return b.counts - a.counts; })
//Start drawing the hexagons
svg.append("g")
.selectAll(".hexagon")
.data(hexData)
.enter().append("path")
.attr("class", "hexagon")
.attr("d", function (d,i) {return "M" + d.x + "," + d.y + hexbin.hexagon(hexSize(d.counts)); })
.attr("stroke", function (d,i) { return d3.rgb(d.color).darker(0.5); })
.attr("stroke-opacity", "0.75")
.attr("stroke-width", "1px")
.style("fill", function (d,i) { return d.color; })
.style("opacity", 0.9)
.on("mouseover", mover)
.on("mouseout", mout);
///////////////////////////////////////////////////////////////////////////
///////////////// Mouse over and Mouse out functions //////////////////////
///////////////////////////////////////////////////////////////////////////
//Function to call when you mouseover a node
function mover(d,i) {
var el = d3.select(this)
.transition().duration(10)
.style("opacity", 1);
$(this).popover({
placement: 'auto top', //place the tooltip above the item
container: '#chart', //the name (class or id) of the container
trigger: 'manual',
html : true,
content: function() { //the html content to show inside the tooltip
return "<span>" + d.color + "</span>"; }
});
$(this).popover('show');
}
//Mouseout function
function mout(d,i) {
var el = d3.select(this)
.transition().duration(1000)
.style("opacity", 0.9);
//Hide the tooltip
$('.popover').each(function() {
$(this).remove();
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment