简体   繁体   中英

How do I make a scatter plot of lines in D3?

I have a series of paired xy coordinates that create 58 lines. I want to plot them on a Cartesian graph, values are between -5 and 5 on both axis, essentially making a scatter plot of lines. I have made something similar in matplotlib using the quiver function, but I want to be able to do this in D3. I would also like to be able to label each line, or each line that meets a length threshold. The code I have come up with below. Thanks.

 var lisa = [["Eloy",0.0169808,-0.695317,-0.0510301,-0.6995938], ["Florence",-0.3465685,-0.6790588,-0.5869514,-0.6762134], ["Phoenix",0.677068,-0.5754814,-0.6052215,-0.6158059], ["Tucson",-0.663848,0.4111043,-0.6722116,0.011639]] var w = 200; var h = 200; //create the svg element and set the height and width parameters var svg = d3.select("div").select("div") .append("svg") .attr("height",h) .attr("width", w) .style("border", "1px solid black"); //Create the scale for the scatter plot var xScale = d3.scale.linear() .domain([d3.min(dataset, function(d) { return d[0];}),d3.max(dataset, function(d) { return d[0];})]) .range([-1,1]); var yScale = d3.scale.linear() .domain([d3.min(dataset, function(d) { return d[1];}),d3.max(dataset, function(d) { return d[1];})]) .range([-1,1]); //This is the function that creates the SVG lines var line = svg.selectAll("line") .data(lisa) .enter() .append("line"); //This gets the cooresponding x,y cordinates from the dataset line.attr("x1", function(d) { return xScale(d[0]); }) .attr("y1", function(d) { return yScale(d[1]); }) .attr("x2", function(d) { return xScale(d[2]); }) .attr("y2", function(d) { return yScale(d[3]); }) .attr("stroke", "black"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

Your code has some problems:

First, your range right now ( [-1, 1] ) makes no sense. This should be the domain instead (I changed the ranges to [0, w] and [0, h] ).

In your real code, the domain should be [-5, 5] and the range should be the limits of the plot, something like [leftLimit, rightLimit] and [topLimit, bottomLimit] (have in mind that, in an SVG, the 0 position for the y axis is the top , not the bottom).

Second, given this array:

["Tucson",-0.663848,0.4111043,-0.6722116,0.011639]

your x and y positions should be the indices 1,2,3 and 4, not 0, 1, 2 and 3.

Besides that changes, I added the labels:

var text = svg.selectAll(".text")
    .data(dataset)
    .enter()
    .append("text");

text.attr("font-size", 10)
    .attr("x", function(d) {
        return xScale(d[1]);
    })
    .attr("y", function(d) {
        return yScale(d[2]);
    })
    .text(d => d[0]);

Here is the demo with the corrections:

 var dataset = [["Eloy",0.0169808,-0.695317,-0.0510301,-0.6995938], ["Florence",-0.3465685,-0.6790588,-0.5869514,-0.6762134], ["Phoenix",0.677068,-0.5754814,-0.6052215,-0.6158059], ["Tucson",-0.663848,0.4111043,-0.6722116,0.011639]]; var color = d3.scale.category10(); var w = 400; var h = 300; //create the svg element and set the height and width parameters var svg = d3.select("body") .append("svg") .attr("height",h) .attr("width", w) .style("border", "1px solid black"); //Create the scale for the scatter plot var xScale = d3.scale.linear() .domain([-1,1]) .range([0,w]); var yScale = d3.scale.linear() .domain([-1,1]) .range([0,h]); //This is the function that creates the SVG lines var line = svg.selectAll("line") .data(dataset) .enter() .append("line"); //This gets the cooresponding x,y cordinates from the dataset line.attr("x1", function(d) { return xScale(d[1]); }) .attr("y1", function(d) { return yScale(d[2]); }) .attr("x2", function(d) { return xScale(d[3]); }) .attr("y2", function(d) { return yScale(d[4]); }) .attr("stroke-width", 2) .attr("stroke", (d,i)=>color(i)); var text = svg.selectAll(".text") .data(dataset) .enter() .append("text"); text.attr("font-size", 10) .attr("x", function(d) { return xScale(d[1])+2; }) .attr("y", function(d) { return yScale(d[2]) + 4; }) .text(d=>d[0]); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM