Skip to content

Scatter Plot

A scatter plot (also called a scatterplot, scatter graph, and scatter diagram) is a type of plot or mathematical diagram using cartesian coordinates to display values for typically two variables for a set of data. The data is displayed as a collection of points, each having the value of one variable determining the position on the horizontal axis and the value of the other variable determining the position on the vertical axis.

ChartFactor supports rendering Scatter Plots with raw data and also aggregated with one and two groups.

Using raw data

The code below renders a Scatter Plot with raw data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
let grid = cf.Grid()
    .top(30)
    .right(25)
    .bottom(35)
    .left(60);
// Define Color Palette
let color = cf.Color()
    .palette(["#0095b7", "yellow"]);
let myChart = cf.provider("Elasticsearch")
    .source("chicago_taxi_trips")
    .fields([
        cf.Field("fare", "fare"),
        cf.Field("tips", "tips")
    ])
    .graph("Scatter Plot")
    .set("grid", grid)
    .limit(1000)
    .execute();

The previous code renders the Scatter Plot below. The first metric in the fields array fare is the x-axis metric. The second metric in the fields array tips is the y-axis metric. Also, notice how we limit the number of points to 1000 using the .limit() function.

Scatter Plot with raw data

Aggregating by one group

The following code shows how to create a Scatter Plot for the top 10 event names with the sum of pricepaid on the x-axis, the sum of qtysold on the y-axis and the sum of commission for the size of the symbols.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    // Define the metrics to be used
    var metrics = [
        cf.Metric("pricepaid", "sum"),
        cf.Metric("qtysold", "sum"),
        cf.Metric("commission", "sum")
    ];

    // define attribute to group by
    var groups = [
        cf.Attribute("eventname.keyword")
            .limit(10)
            .sort("desc", metrics[0])
    ];
    var myChart = cf.provider("Elasticsearch")
        .source("ticket_sales")
        .groupby(...groups)
        .metrics(...metrics)
        .graph("Scatter Plot")
        .element("chart")
        .execute();

Previous code renders the Scatter Plot shown below.

Scatter Plot aggregated by one group

The three metrics in the code definition represent in order: pricepaid the x-Axis, qtysold the y-Axis and commission the size of the synbols.

Aggregating by two groups

The following code shows how to create a Scatter Plot where each symbol is the combination of the top 100 event names and the top 4 category names, with the sum of pricepaid on the x-axis, the sum of qtysold on the y-axis and the sum of commission driving the symbol size.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    // Define the metrics to be used
    var metrics = [
        cf.Metric("pricepaid", "sum"),
        cf.Metric("qtysold", "sum"),
        cf.Metric("commission", "sum")
    ];

    // define attribute to group by
    var groups = [
        cf.Attribute("eventname.keyword").label('Event')
            .limit(100)
            .sort("desc", metrics[0]),
        cf.Attribute("catname.keyword").label('Category')
            .limit(4)
            .sort("desc", metrics[0])
    ];
    var myChart = cf.provider("Elasticsearch")
        .source("ticket_sales")
        .groupby(...groups)
        .metrics(...metrics)
        .set("legend", "top")
        .graph("Scatter Plot")
        .element("chart");

The previous code renders the Scatter Plot below. Note that color is driven by the second group catname.keyword. The legend at the top of the chart shows each category with its assigned color. For example, the symbols for the Plays category are filled with the color green.

Scatter Plot aggregated by two groups

Configuring symbols

ChartFactor supports defining different symbols for your Scatter Plot. The symbol object supports the settings below.

  • color: text Color
  • borderColor: text Color
  • borderWidth: Number
  • opacity: Number
  • form: circle | rect | roundRect | triangle | diamond | pin | arrow
  • size: Number

Example:

1
2
3
4
5
6
7
8
let symbol = {
    color: "#0095b7",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 1,
    form: "pin",
    size: 35,
};

Symbols for raw data

When rendering a Scatter Plot with unaggregated data, you can plot several metrics on the y-axis and assign different symbols to each of them to differentiate them. To do this, first define individual symbol objects.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
let symbol = {
    color: "#fe8b3e",
    borderColor: "#756ccc",
    borderWidth: 1,
    opacity: 0.8,
    form: "rect",
    size: 10,
};
let symbol2 = {
    color: "#a0b774",
    borderColor: "#756ccc",
    borderWidth: 1,
    opacity: 0.4,
    form: "circle",
};

Second, define a symbolFieldMatch object where the keys are the field names of the y-axis metrics and the values are the symbol objects. Example below.

1
2
3
4
let symbolFieldMatch = { 
    "tips": symbol,
    "trip_total": symbol2,
};

Finally, use the symbolFieldMatch setting to set your symbolFieldMatch object to your visualization.

The following is a full example of a Scatter Plot rendering unaggregated data. On the x-axis, it renders fare which is the first field in the fields array. On the y-axis, it renders tips, trip_total, and tolls which are the next fields in the fields array. It then uses the symbolFieldMatch setting to enable the symbol match functionality for tips, trip_total, and tolls. Additionally, it defines a default symbol using the symbol setting.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
let grid = cf.Grid()
    .top(30)
    .right(40)
    .bottom(35)
    .left(60);
let symbol = {
    color: "#fe8b3e",
    borderColor: "#756ccc",
    borderWidth: 1,
    opacity: 0.8,
    form: "rect",
    size: 10,
};
let symbol2 = {
    color: "#a0b774",
    borderColor: "#756ccc",
    borderWidth: 1,
    opacity: 0.4,
    form: "circle",
};
let symbol3 = {
    color: "#cf2f23",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 0.6,
    form: "diamond",
    size: 25,
};
let legend = cf.Legend()
    .position("right")
    .width(150)
    .height("95%")
    .sort("none");
let myChart = cf.provider("Elasticsearch")
    .source("chicago_taxi_trips")
    .fields([
        cf.Field("fare", "fare"),
        cf.Field("tips", "tips"),
        cf.Field("trip_total", "trip_total"),
        cf.Field("tolls", "tolls")
    ])
    .graph("Scatter Plot")
    .set("grid", grid)
    .set("symbol", symbol)   // default symbol setting
    .set("symbolFieldMatch", // symbol field match setting
        { "tips": symbol, "trip_total": symbol3, "tolls": symbol2 }
    )
    .set("legend", "top")
    .execute();

The previous code renders the Scatter Plot below.

Scatter Plot with different symbols for different y-axis metric fields

Symbol size

For Scatter Plots with raw data, the size of symbols can be driven by one of the metric fields in your fields array. To do that, use the symbolFieldSize setting to specify the metric field that drives the size of the symbols. Example:

1
.set("symbolFieldSize", "trip_total")

Additionally, you can use the size property of each symbol object to control the size of a specific symbol type. Because this property is more specific, it has higher prescedence and overrides the symbolFieldSize setting.

Symbols for aggregate data

You can configure different symbols for different aggregate values using the Symbol Match functionality. To do this, first define individual symbol objects.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
let symbol1 = {
    color: "#0095b7",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 1,
    form: "pin",
    size: 35,
};
let symbol2 = {
    color: "#cf2f23",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 1,
    form: "circle",
    size: 35,
};

Second, define a symbolMatch object where the keys are the group values and the values are the symbol objects. Example below.

1
2
3
4
let symbolMatch = {
    "Near North Side": symbol1,
    "Near West Side": symbol2
};
Finally, use the symbolMatch setting to set your symbolMatch object to your visualization.

The following is a full example of a Scatter Plot aggregating data by dropoff_community_area_desc and using the symbolMatch setting to enable the symbol match functionality for the "Near North Side" and for the "Near West Side" dropoff community areas. Additionally, it defines the default symbol using the symbol setting.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
let grid = cf.Grid()
    .top(10)
    .right(25)
    .bottom(35)
    .left(40);
let symbol = {
    color: "#fe8b3e",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 0.8,
    form: "roundRect",
    size: 15,
};
let symbol2 = {
    color: "#0095b7",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 1,
    form: "pin",
    size: 35,
};
let symbol3 = {
    color: "#cf2f23",
    borderColor: "#756ccc",
    borderWidth: 2,
    opacity: 1,
    form: "circle",
    size: 35,
};
let symbolMatch = {
    "Near North Side": symbol2,
    "Near West Side": symbol3
};
let metrics = [
    cf.Metric("extras", "sum"),
    cf.Metric("fare", "sum"),
    cf.Metric("tips", "sum")
];
let group1 = cf.Attribute("dropoff_community_area_desc")
    .limit(10)
    .sort("desc", cf.Metric("extras", "sum"));
let myChart = cf.provider("Elasticsearch")
    .source("chicago_taxi_trips")
    .groupby(group1)
    .metrics(...metrics)
    .set("grid", grid)
    .set("symbol", symbol)              // default symbol
    .set("symbolMatch", symbolMatch)    // symbol match setting
    .set("legend", "right")
    .graph("Scatter Plot")
    .execute();

The previous code will render the following Scatter Plot with groups:

Scatter Plot with different symbols for different aggregate values

Symbol size

For Scatter Plots with aggregate data, the size of symbols is driven by the third metric in the metrics array. Additionally, you can use the size property of the symbol object to control the size of a specific symbol type. Because this property is more specific, it has higher prescedence and overrides the size behavior driven by the third metric.