D3.js: How to make a complete data display different colors according to a certain standard classification?

Hi, all
I have a piece of data that I want to categorize by cell or lib (depending on the user’s choice). What should I do?
Thank you for your advance help.

//colored represents the user's choice(cell or lib) 
//colorArr represents the length of the color to be drawn
var data=[{"x": -0.44972, "y": 0.1771, "cell": "I1", "lib": "S5"}, {"x": 0.19, "y": 0.752, "cell": "I1", "lib": "S6"}, {"x": -0.21137, "y": -0.2388, "cell": "I1", "lib": "S3"}, {"x": -0.0348, "y": 0.01171,  "cell": "I1", "lib": "S6"}, {"x": -0.357, "y": 0.822,  "cell": "I1", "lib": "S6"}, {"x": -0.2543, "y": -0.3184, "cell": "I1", "lib": "S6"}, {"x": -0.1235, "y": 0.2822,  "cell": "I3", "lib": "S6"}, {"x": -0.43765, "y": -0.34685, "cell": "I1", "lib": "S6"}]
      var color = d3
        .scaleLinear()
        .domain([0, 1]) // Points per square pixel.
        .range( [
        "#e31a1c",
        "#1f78b4",
        "#ff7f00",
        "#b2df8a",
        "#87843b",
        "#fb9a99",
        "#8dd3c7"]);
svg
        .append("g")
        .selectAll()
        .data(data)
        .join("circle")
        .attr("cx", (d) => x(d.umap_x))
        .attr("cy", (d) => y(d.umap_y))
        .attr("r", 2);

Kindly change your code according to this…

// colored represents the user’s choice(cell or lib)
// colorArr represents the length of the color to be drawn

var data = [{“x”: -0.44972, “y”: 0.1771, “cell”: “I1”, “lib”: “S5”}, {“x”: 0.19, “y”: 0.752, “cell”: “I1”, “lib”: “S6”}, {“x”: -0.21137, “y”: -0.2388, “cell”: “I1”, “lib”: “S3”}, {“x”: -0.0348, “y”: 0.01171, “cell”: “I1”, “lib”: “S6”}, {“x”: -0.357, “y”: 0.822, “cell”: “I1”, “lib”: “S6”}, {“x”: -0.2543, “y”: -0.3184, “cell”: “I1”, “lib”: “S6”}, {“x”: -0.1235, “y”: 0.2822, “cell”: “I3”, “lib”: “S6”}, {“x”: -0.43765, “y”: -0.34685, “cell”: “I1”, “lib”: “S6”}]

// get color domain based on lib
// data.map((d)=> d.lib) will return [“S5”, “S6”, “S3”, “S6”, “S6”, “S6”, “S6”, “S6”];
// to get unique value from array
// colorDomain = [ … new Set([“S5”, “S6”, “S3”, “S6”, “S6”, “S6”, “S6”, “S6”]) ] will return [“S5”, “S6”, “S3”]
const colorDomain = [“S5”, “S6”, “S3”]
const colorRange = [ “#e31a1c”, “#1f78b4”,“#ff7f00”, “#b2df8a”, “#87843b”,“#fb9a99”,“#8dd3c7”]

const colorScale = d3
.scaleOrdinal()
.domain(colorDomain)
.range(colorRange);

  svg.append("g")
    .selectAll()
    .data(data)
    .join("circle")
    .attr("cx", (d) => x(d.umap_x))
    .attr("cy", (d) => y(d.umap_y))
    .attr("r", 2)
	.attr("fill", (d)=> colorScale(d.lib))

Thank you, I tried your method. Scatter plots are okay, but why doesn’t 2D density plots work?

svg
        .append("g")
        .attr("stroke-width", 2)
        .selectAll()
        .data(
          d3
            .contourDensity()
            .x(function (d) {
              return x(d.x);
            })
            .y(function (d) {
              return y(d.y);
            })
            .size([width, height])
            .bandwidth(30)
            .thresholds(30)(data)
        )
        .join("path")
        .attr("stroke", (d) => colorScale(d.lib)
        .attr("d", d3.geoPath());

I think you should use fill instead of stroke

.attr(“fill”, (d) => colorScale(d.lib))

I’m sorry, but that won’t work.

.attr("stroke", (d) => { 
// kindly console.log(d) and show me the output
console.log(d)
return colorScale(d.lib) 
}

I think the data when printing is not my original data, so I cannot use lib for classification, this has been processed through code.

 .data(
          d3
            .contourDensity()
            .x(function (d) {
              return x(d.x);
            })
            .y(function (d) {
              return y(d.y);
            })
            .size([width, height])
            .bandwidth(20)
            .thresholds(20)(data)
        )

use this code

.attr("fill", function(d,i)  { 
console.log(data[i].lib);
return colorScale(data[i].lib); 
})

Raw data can be printed out, but cannot be classified.

kindly try me codepan link

I tried your code and found that the result was correct. Then I combined your code with my data and found that the result was incorrect. There are over 70000 pieces of my data, and the result is shown in the following figure:


I found that your logic seems to be incorrect. The code written in this way is not classified based on the lib of the original data, and at this time, I refers to the number of turns.