Skip to content

Instantly share code, notes, and snippets.

@curran
Last active September 12, 2015 21:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save curran/3cc1a2a289dddbd64688 to your computer and use it in GitHub Desktop.
Save curran/3cc1a2a289dddbd64688 to your computer and use it in GitHub Desktop.
Fundamental Visualizations

Fundamental visualization techniques as Chiasm plugins. Inspired by:

Goals of this example:

  • Provide a starting point for developing more advanced visualization components. Directions to go from here include adding axes, labels, legends, tooltips, and brushing.

  • Show how each visualization technique can be encapsulated as a standalone piece of code, with no shared dependencies between components. This is why, for example, code for margins and styling is duplicated code in many components. These things could conveivably be refactored out into common modules shared between visualization components.

For a more advanced example that adds brushing interaction to a scatter plot, check out Focus + Context Scatter Plots.

Data includes:

web counter
// This is an example Chaism plugin that uses D3 to make a bar chart.
// Draws from this Bar Chart example http://bl.ocks.org/mbostock/3885304
function BarChart() {
var my = ChiasmComponent({
margin: {
left: 30,
top: 30,
right: 30,
bottom: 30
},
barSizeColumn: Model.None,
// These properties adjust spacing between bars.
// The names correspond to the arguments passed to
// d3.scale.ordinal.rangeRoundBands(interval[, padding[, outerPadding]])
// https://github.com/mbostock/d3/wiki/Ordinal-Scales#ordinal_rangeRoundBands
barPadding: 0.1,
barOuterPadding: 0.1,
fill: "black",
stroke: "none",
strokeWidth: "1px",
orientation: "vertical"
});
var barSizeScale = d3.scale.linear();
var barIdentityScale = d3.scale.ordinal();
my.el = document.createElement("div");
var svg = d3.select(my.el).append("svg");
var g = svg.append("g");
// Respond to changes in size and margin.
// Inspired by D3 margin convention from http://bl.ocks.org/mbostock/3019563
my.when(["box", "margin"], function(box, margin){
my.innerBox = {
width: box.width - margin.left - margin.right,
height: box.height - margin.top - margin.bottom
};
svg
.attr("width", box.width)
.attr("height", box.height);
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
});
my.when(["data", "barSizeColumn", "innerBox", "barPadding", "barOuterPadding", "fill", "stroke", "strokeWidth", "orientation"],
function (data, barSizeColumn, innerBox, barPadding, barOuterPadding, fill, stroke, strokeWidth, orientation){
var x, y, width, height;
barSizeScale
.domain([0, d3.max(data, function (d){ return d[barSizeColumn]; })]);
barIdentityScale
.domain(d3.range(data.length));
if(orientation === "vertical"){
barSizeScale.range([innerBox.height, 0]);
barIdentityScale.rangeRoundBands([0, innerBox.width], barPadding, barOuterPadding);
x = function(d, i) { return barIdentityScale(i); };
y = function(d) { return barSizeScale(d[barSizeColumn]); };
width = barIdentityScale.rangeBand();
height = function(d) { return innerBox.height - y(d); };
} else if(orientation === "horizontal"){
barSizeScale.range([0, innerBox.width]);
barIdentityScale.rangeRoundBands([0, innerBox.height], barPadding, barOuterPadding);
x = 0;
y = function(d, i) { return barIdentityScale(i); };
width = function(d) { return barSizeScale(d[barSizeColumn]); };
height = barIdentityScale.rangeBand();
}
var bars = g.selectAll("rect").data(data);
bars.enter().append("rect");
bars
.attr("x", x)
.attr("width", width)
.attr("y", y)
.attr("height", height)
.attr("fill", fill)
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth);
bars.exit().remove();
});
return my;
}
name amount
A 18
B 20
C 15
D 35
E 12
{
"columns": [
{ "name": "name", "type": "string" },
{ "name": "amount", "type": "number" }
]
}
{
"layout": {
"plugin": "layout",
"state": {
"containerSelector": "#chiasm-container",
"layout": {
"orientation": "vertical",
"children": [
{
"orientation": "horizontal",
"children": [
"scatterPlot",
"pieChart",
"barChartVertical",
"barChartHorizontal"
]
},
{
"orientation": "horizontal",
"children": [
"scatterPlotSize",
"donutChart",
"lineChart",
"choropleth"
]
}
]
},
"sizes": {
"lineChart": {
"size": 1
}
}
}
},
"scatterPlotData": {
"plugin": "dataLoader",
"state": {
"path": "scatterPlotData"
}
},
"scatterPlot": {
"plugin": "scatterPlot",
"state": {
"xColumn": "sepal_length",
"yColumn": "petal_length"
}
},
"scatterPlotSize": {
"plugin": "scatterPlot",
"state": {
"xColumn": "sepal_length",
"yColumn": "petal_length",
"rColumn": "sepal_length",
"rMax": 20,
"fill": "none",
"stroke": "black",
"strokeWidth": "2px"
}
},
"pieChartData": {
"plugin": "dataLoader",
"state": {
"path": "pieChartData"
}
},
"pieChart": {
"plugin": "pieChart",
"state": {
"sliceColumn": "population",
"fill": "none",
"stroke": "black",
"strokeWidth": "2px"
}
},
"donutChart": {
"plugin": "pieChart",
"state": {
"sliceColumn": "population",
"donutHoleSize": 0.5,
"fill": "none",
"stroke": "black",
"strokeWidth": "2px"
}
},
"barChartData": {
"plugin": "dataLoader",
"state": {
"path": "barChartData"
}
},
"barChartVertical": {
"plugin": "barChart",
"state": {
"barSizeColumn": "amount",
"fill": "none",
"stroke": "black",
"strokeWidth": "2px",
"barPadding": 0.2
}
},
"barChartHorizontal": {
"plugin": "barChart",
"state": {
"orientation": "horizontal",
"barSizeColumn": "amount",
"fill": "none",
"stroke": "black",
"strokeWidth": "2px",
"barPadding": 0.2
}
},
"lineChart": {
"plugin": "lineChart",
"state": {
"yColumn": "amnt",
"stroke": "black",
"strokeWidth": "2px"
}
},
"choropleth": {
"plugin": "choropleth",
"state": {
"stroke": "black",
"strokeWidth": "2px",
"scale": 300,
"idColumn": "geoId",
"topoDataIdProperty": "GEOID10",
"colorColumn": "population"
}
},
"links": {
"plugin": "links",
"state": {
"bindings": [
"pieChartData.data -> pieChart.data",
"pieChartData.data -> donutChart.data",
"scatterPlotData.data -> scatterPlot.data",
"scatterPlotData.data -> scatterPlotSize.data",
"barChartData.data -> barChartVertical.data",
"barChartData.data -> barChartHorizontal.data"
]
}
}
}
// This is an example Chaism plugin that uses D3 to make a Choropleth Map.
// Draws from this Choropleth example http://bl.ocks.org/mbostock/4060606
function Choropleth() {
var my = ChiasmComponent({
colorColumn: Model.None,
idColumn: Model.None,
topoDataIdProperty: Model.None,
stroke: "gray",
strokeWidth: "1px",
scale: 1280
});
var quantize = d3.scale.quantize();
var projection = d3.geo.albersUsa();
var geoPath = d3.geo.path()
.projection(projection);
my.el = document.createElement("div");
var svg = d3.select(my.el).append("svg");
var g = svg.append("g");
my.when("box", function (box) {
svg
.attr("width", box.width)
.attr("height", box.height);
});
my.when(["data", "idColumn", "colorColumn", "topoDataIdProperty"],
function (data, idColumn, colorColumn, topoDataIdProperty){
if(colorColumn === Model.None) return;
if(idColumn === Model.None) return;
if(topoDataIdProperty === Model.None) return;
quantize.domain(d3.extent(data, function (d) { return d[colorColumn]; }));
// Grays from http://bl.ocks.org/mbostock/5577023
// TODO move this to config.
quantize.range(["#f7f7f7","#cccccc","#969696","#636363","#252525"]);
var valueById = d3.map();
data.forEach(function(d) {
valueById.set(d[idColumn], d[colorColumn]);
});
my.fill = function(d) {
var id = d.properties[topoDataIdProperty];
return quantize(valueById.get(id));
};
});
my.when(["topoData", "fill", "box", "scale", "stroke", "strokeWidth" ],
function (topoData, fill, box, scale, stroke, strokeWidth){
projection.scale(scale);
projection.translate([box.width / 2, box.height / 2]);
var topoDataObjectName = "State_2010Census_DP1";
var topoDataObject = topoData.objects[topoDataObjectName];
var features = topojson.feature(topoData, topoDataObject).features;
var path = g.selectAll("path").data(features);
path.enter().append("path");
path.exit().remove();
path
.attr("d", geoPath)
.attr("fill", fill)
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth);
});
return my;
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
// A Chiasm plugin for loading DSV data sets.
function DataLoader (){
var my = ChiasmComponent({
path: Model.None
});
my.when("path", function (path){
d3.json(path + ".json", function(error, schema) {
var numericColumns = schema.columns.filter(function (column){
return column.type === "number";
});
var type = function (d){
numericColumns.forEach(function (column){
d[column.name] = +d[column.name];
});
return d;
}
d3.csv(path + ".csv", type, function(error, data) {
my.data = data;
});
});
});
return my;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fundamental Visualizations</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<!-- The date parsing for the line chart data uses Moment.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<!-- The Choropleth component uses TopoJSON. -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<!-- A functional reactive model library. github.com/curran/model -->
<script src="http://curran.github.io/model/cdn/model-v0.2.4.js"></script>
<!-- Chiasm core and plugins. github.com/chiasm-project -->
<script src="http://chiasm-project.github.io/chiasm/chiasm-v0.2.0.js"></script>
<script src="http://chiasm-project.github.io/chiasm-component/chiasm-component-v0.2.1.js"></script>
<script src="http://chiasm-project.github.io/chiasm-layout/chiasm-layout-v0.2.2.js"></script>
<script src="http://chiasm-project.github.io/chiasm-links/chiasm-links-v0.2.0.js"></script>
<!-- Custom Chiasm plugins for this example. -->
<script src="dataLoader.js"></script>
<script src="pieChart.js"></script>
<script src="scatterPlot.js"></script>
<script src="barChart.js"></script>
<script src="lineChart.js"></script>
<script src="choropleth.js"></script>
<style>
body {
background-color: black;
}
/* Make the chart container fill the page using CSS. */
#chiasm-container {
background-color: white;
position: fixed;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
}
</style>
</head>
<body>
<div id="chiasm-container"></div>
<script>
var chiasm = Chiasm();
chiasm.plugins.layout = ChiasmLayout;
chiasm.plugins.links = ChiasmLinks;
chiasm.plugins.dataLoader = DataLoader;
chiasm.plugins.pieChart = PieChart;
chiasm.plugins.scatterPlot = ScatterPlot;
chiasm.plugins.barChart = BarChart;
chiasm.plugins.lineChart = LineChart;
chiasm.plugins.choropleth = Choropleth;
// Use D3 to fetch the chiasm configuration file and
// Set the Chaism application configuration.
d3.json("chiasmConfig.json", function (config){
chiasm.setConfig(config);
});
// Set up the line chart component with data from William Playfair.
chiasm.getComponent("lineChart").then(function (lineChart){
// Fetch the JSON version of the data for the line chart.
d3.json("lineChartData.json", function (lineChartData){
// Do a custom data transform to make it the table structure that the
// line chart component understands.
var data = lineChartData.year.map(function (yearStr, i){
return {
year: moment(yearStr).toDate(),
imports_minus_exports: lineChartData.imports_minus_exports[i]
};
});
// Configure the line chart with the data.
lineChart.set({
data: data,
xColumn: "year",
yColumn: "imports_minus_exports"
});
});
});
// Set up the choropleth component with data from the US Census.
chiasm.getComponent("choropleth").then(function (choropleth){
// Fetch the JSON version of the data for the line chart.
d3.json("choroplethData.json", function (topoData){
var geometries = topoData.objects.State_2010Census_DP1.geometries;
var data = geometries.map(function (d){
return {
geoId: d.properties.GEOID10,
population: d.properties.DP0010001
};
});
// Configure the line chart with the data.
choropleth.set({
topoData: topoData,
data: data
});
});
});
</script>
</body>
</html>
// This is an example Chaism plugin that uses D3 to make a line chart.
// Draws from this Line Chart example http://bl.ocks.org/curran/60b40877ef898f19aeb8
function LineChart() {
var my = ChiasmComponent({
margin: {
left: 30,
top: 30,
right: 30,
bottom: 30
},
yColumn: Model.None,
xColumn: Model.None,
fill: "none",
stroke: "gray",
strokeWidth: "1px"
});
var xScale = d3.time.scale();
var yScale = d3.scale.linear();
my.el = document.createElement("div");
var svg = d3.select(my.el).append("svg");
var g = svg.append("g");
var path = g.append("path");
// Respond to changes in size and margin.
// Inspired by D3 margin convention from http://bl.ocks.org/mbostock/3019563
my.when(["box", "margin"], function(box, margin){
my.innerBox = {
width: box.width - margin.left - margin.right,
height: box.height - margin.top - margin.bottom
};
svg
.attr("width", box.width)
.attr("height", box.height);
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
});
var line = d3.svg.line();
my.when(["data", "innerBox", "xColumn", "yColumn"],
function (data, innerBox, xColumn, yColumn){
if(xColumn !== Model.None){
xScale.range([0, innerBox.width]);
xScale.domain(d3.extent(data, function (d){ return d[xColumn]; }));
my.x = function (d){ return xScale(d[xColumn]); };
}
if(yColumn !== Model.None){
yScale.range([innerBox.height, 0]);
yScale.domain(d3.extent(data, function (d){ return d[yColumn]; }));
my.y = function (d){ return yScale(d[yColumn]); };
}
});
my.when(["data", "x", "y", "fill", "stroke", "strokeWidth"],
function (data, x, y, fill, stroke, strokeWidth){
path
.attr("d", line.x(x).y(y)(data))
.attr("fill", fill)
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth);
});
return my;
}
{
"year": [ "1700-01-01", "1701-01-01", "1702-01-01", "1703-01-01", "1704-01-01", "1705-01-01", "1706-01-01", "1707-01-01", "1708-01-01", "1709-01-01", "1710-01-01", "1711-01-01", "1712-01-01", "1713-01-01", "1714-01-01", "1715-01-01", "1716-01-01", "1717-01-01", "1718-01-01", "1719-01-01", "1720-01-01", "1721-01-01", "1722-01-01", "1723-01-01", "1724-01-01", "1725-01-01", "1726-01-01", "1727-01-01", "1728-01-01", "1729-01-01", "1730-01-01", "1731-01-01", "1732-01-01", "1733-01-01", "1734-01-01", "1735-01-01", "1736-01-01", "1737-01-01", "1738-01-01", "1739-01-01", "1740-01-01", "1741-01-01", "1742-01-01", "1743-01-01", "1744-01-01", "1745-01-01", "1746-01-01", "1747-01-01", "1748-01-01", "1749-01-01", "1750-01-01", "1751-01-01", "1752-01-01", "1753-01-01", "1754-01-01", "1755-01-01", "1756-01-01", "1757-01-01", "1758-01-01", "1759-01-01", "1760-01-01", "1761-01-01", "1762-01-01", "1763-01-01", "1764-01-01", "1765-01-01", "1766-01-01", "1767-01-01", "1768-01-01", "1769-01-01", "1770-01-01", "1771-01-01", "1772-01-01", "1773-01-01", "1774-01-01", "1775-01-01", "1776-01-01", "1777-01-01", "1778-01-01", "1779-01-01", "1780-01-01"],
"imports_minus_exports": [ 0.295918368, 0.308163266, 0.322448979, 0.342857142, 0.36122449, 0.385714285, 0.418367347, 0.442857143, 0.455102041, 0.475510204, 0.5, 0.5224489800000001, 0.571428571, 0.595918368, 0.612244898, 0.63877551, 0.665306123, 0.6918367350000001, 0.7183673469999999, 0.74489796, 0.751020408, 0.7755102039999999, 0.785714286, 0.797959183, 0.81632653, 0.826530612, 0.8244897959999999, 0.826530612, 0.836734694, 0.8469387749999999, 0.8469387749999999, 0.8469387749999999, 0.836734694, 0.826530612, 0.806122449, 0.7653061219999999, 0.732653061, 0.7081632660000001, 0.673469388, 0.640816326, 0.6224489799999999, 0.591836735, 0.56122449, 0.5306122449999999, 0.510204082, 0.489795919, 0.469387755, 0.4285714279999999, 0.37755102, 0.3469387749999999, 0.285714285, 0.230612245, 0.173469387, 0.1122448979999999, 0.06530612199999997, 0.03061224500000004, 0.03469387800000001, 0.04081632700000004, 0.071428571, 0.081632653, 0.132653061, 0.204081632, 0.397959183, 0.3959183669999999, 0.3653061230000001, 0.2142857150000002, 0.1326530610000001, 0.1326530609999999, 0.1387755099999999, 0.167346939, 0.2, 0.2346938779999999, 0.275510205, 0.336734694, 0.418367347, 0.581632654, 0.626530612, 0.6714285720000001, 0.6857142849999999, 0.7000000000000001, 0.7142857140000001, 0.295918368, 0.308163266, 0.322448979, 0.342857142, 0.36122449, 0.385714285, 0.418367347, 0.442857143, 0.455102041, 0.475510204, 0.5, 0.5224489800000001, 0.571428571, 0.595918368, 0.612244898, 0.63877551, 0.665306123, 0.6918367350000001, 0.7183673469999999, 0.74489796, 0.751020408, 0.7755102039999999, 0.785714286, 0.797959183, 0.81632653, 0.826530612, 0.8244897959999999, 0.826530612, 0.836734694, 0.8469387749999999, 0.8469387749999999, 0.8469387749999999, 0.836734694, 0.826530612, 0.806122449, 0.7653061219999999, 0.732653061, 0.7081632660000001, 0.673469388, 0.640816326, 0.6224489799999999, 0.591836735, 0.56122449, 0.5306122449999999, 0.510204082, 0.489795919, 0.469387755, 0.4285714279999999, 0.37755102, 0.3469387749999999, 0.285714285, 0.230612245, 0.173469387, 0.1122448979999999, 0.06530612199999997, 0.03061224500000004, 0.03469387800000001, 0.04081632700000004, 0.071428571, 0.081632653, 0.132653061, 0.204081632, 0.397959183, 0.3959183669999999, 0.3653061230000001, 0.2142857150000002, 0.1326530610000001, 0.1326530609999999, 0.1387755099999999, 0.167346939, 0.2, 0.2346938779999999, 0.275510205, 0.336734694, 0.418367347, 0.581632654, 0.626530612, 0.6714285720000001, 0.6857142849999999, 0.7000000000000001, 0.7142857140000001 ]
}
// This is an example Chaism plugin that uses D3 to make a pie chart.
// Draws from this Pie Chart example http://bl.ocks.org/mbostock/3887235
function PieChart() {
var my = ChiasmComponent({
// This property specifies which column of the input data should be used to
// determine the size of each slice of the pie chart.
sliceColumn: Model.None,
// This number varies between 0 and 1. Any value other than 0 converts the
// visualization from a pie chart to a donut chart.
//
// 0 = a pie chart,
// 0.5 = a thick donut chart
// 0.9 = a thin donut chart
donutHoleSize: 0,
// The margin (in pixels) on all sides of the pie chart.
margin: 10,
fill: "none",
stroke: "gray",
strokeWidth: "1px"
});
var arc = d3.svg.arc();
var pie = d3.layout.pie().sort(null);
var g = d3.select(my.initSVG()).append("g");
my.when(["data", "box", "sliceColumn", "donutHoleSize", "margin", "fill", "stroke", "strokeWidth" ],
function (data, box, sliceColumn, donutHoleSize, margin, fill, stroke, strokeWidth){
pie.value(function(d) { return d[sliceColumn]; });
var arcPath = g.selectAll("path").data(pie(data));
var radius = Math.min(box.width, box.height) / 2 - margin;
arc.outerRadius(radius);
arc.innerRadius(donutHoleSize * radius);
arcPath.enter().append("path");
arcPath.exit().remove();
arcPath
.attr("d", arc)
.attr("fill", fill)
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth);
});
my.when("box", function (box) {
g.attr("transform", "translate(" + box.width / 2 + "," + box.height / 2 + ")");
});
return my;
}
age population
<5 2704659
5-13 4499890
14-17 2159981
18-24 3853788
25-44 14106543
45-64 8819342
≥65 612463
{
"columns": [
{ "name": "age", "type": "string" },
{ "name": "population", "type": "number" }
]
}
// This is an example Chaism plugin that uses D3 to make a scatter plot.
// Draws from this Scatter Plot example http://bl.ocks.org/curran/134ed87c99257e3f2e31
function ScatterPlot() {
var my = ChiasmComponent({
margin: {
left: 30,
top: 30,
right: 30,
bottom: 30
},
xColumn: Model.None,
yColumn: Model.None,
// "r" stands for radius.
rColumn: Model.None,
// The circle radius used if rColumn is not specified.
rDefault: 3,
// The range of the radius scale if rColumn is specified.
rMin: 0,
rMax: 10,
fill: "black",
stroke: "none",
strokeWidth: "1px"
});
var xScale = d3.scale.linear();
var yScale = d3.scale.linear();
var rScale = d3.scale.sqrt();
var g = d3.select(my.initSVG()).append("g");
// Respond to changes in size and margin.
// Inspired by D3 margin convention from http://bl.ocks.org/mbostock/3019563
my.when(["box", "margin"], function(box, margin){
my.innerBox = {
width: box.width - margin.left - margin.right,
height: box.height - margin.top - margin.bottom
};
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
});
my.when(["data", "innerBox", "xColumn"], function (data, innerBox, xColumn){
if(xColumn !== Model.None){
xScale.range([0, innerBox.width]);
xScale.domain(d3.extent(data, function (d){ return d[xColumn]; }));
my.x = function (d){ return xScale(d[xColumn]); };
}
});
my.when(["data", "innerBox", "yColumn"], function (data, innerBox, yColumn){
if(yColumn !== Model.None){
yScale.range([innerBox.height, 0]);
yScale.domain(d3.extent(data, function (d){ return d[yColumn]; }));
my.y = function (d){ return yScale(d[yColumn]); };
}
});
// Generate a function or constant for circle radius,
// depending on whether or not rColumn is defined.
my.when(["data", "rColumn", "rDefault", "rMin", "rMax"],
function (data, rColumn, rDefault, rMin, rMax){
if(rColumn === Model.None){
my.r = rDefault;
} else {
rScale
.domain(d3.extent(data, function (d){ return d[rColumn]; }))
.range([rMin, rMax]);
my.r = function (d){ return rScale(d[rColumn]); };
}
});
my.when([ "data", "x", "y", "r", "fill", "stroke", "strokeWidth" ],
function (data, x, y, r, fill, stroke, strokeWidth){
var circles = g.selectAll("circle").data(data);
circles.enter().append("circle");
circles.exit().remove();
circles
.attr("cx", x)
.attr("cy", y)
.attr("r", r)
.attr("fill", fill)
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth);
});
return my;
}
sepal_length sepal_width petal_length petal_width class
5.0 3.4 1.5 0.2 setosa
4.8 3.4 1.6 0.2 setosa
5.1 3.5 1.4 0.3 setosa
5.4 3.4 1.7 0.2 setosa
5.0 3.4 1.6 0.4 setosa
4.4 3.0 1.3 0.2 setosa
5.0 3.5 1.3 0.3 setosa
4.6 3.2 1.4 0.2 setosa
6.9 3.1 4.9 1.5 versicolor
5.9 3.0 4.2 1.5 versicolor
5.8 2.7 4.1 1.0 versicolor
6.1 2.8 4.0 1.3 versicolor
5.7 2.6 3.5 1.0 versicolor
5.5 2.4 3.8 1.1 versicolor
5.6 3.0 4.1 1.3 versicolor
5.8 2.6 4.0 1.2 versicolor
5.1 2.5 3.0 1.1 versicolor
5.8 2.7 5.1 1.9 virginica
7.3 2.9 6.3 1.8 virginica
6.8 3.0 5.5 2.1 virginica
6.0 2.2 5.0 1.5 virginica
5.6 2.8 4.9 2.0 virginica
6.3 2.8 5.1 1.5 virginica
6.9 3.1 5.4 2.1 virginica
6.2 3.4 5.4 2.3 virginica
{
"columns": [
{ "name": "sepal_length", "type": "number" },
{ "name": "sepal_width", "type": "number" },
{ "name": "petal_length", "type": "number" },
{ "name": "petal_width", "type": "number" },
{ "name": "class", "type": "string" }
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment