Correlation - Scatterplot Matrix

From Q
Jump to navigation Jump to search
VizIcon Scatterplot Matrix.svg

Shows a matrix where the lower triangle displays scatterplots of variable pairs, the diagonal displays variable histograms and the upper triangle displays correlations of variable pairs. Also known as a scatter plot matrix or SPLOM.

How to Create a Scatterplot Matrix

  1. Add the object by selecting from the menu Anything > Advanced Analysis > Correlation > Scatterplot MatrixCreate > Correlation > Scatterplot Matrix
  2. Under Inputs > Variables to plot select the variables to include in the matrix.

Examples

An example of a scatterplot matrix with 3 variables and fitted LOESS curves:

An example of a scatterplot matrix with categorical variables:

Options

The options in the Object Inspector are organized into three tabs: Inputs, Properties, Chart.

Inputs

Variables to plot The variables that will be shown in the matrix. These can be numeric, categorical or ordered categorical.

Variable names Whether to show variable names in the matrix, instead of variable labels.

Missing data Method for dealing with missing data. See Missing Data Options.

Error if missing data
Exclude cases with missing data
Use partial data

Fitted line

None No fitted line is shown in each scatterplot.
Straight A line of best fit (from linear regression) is shown in each scatterplot.
LOESS A line generated using fitted values from locally weighted polynomial regression is shown in each scatterplot.

Scatter point type The type of plot point to display.

Small dots
Dots
Big dots
Circles

Scatter point modifications

None No modifications.
Jitter Add noise to each point so that areas with closely positioned points appear denser.
Enlarge points with multiple observations Multiple points with identical positions will appear as an enlarged point. This is the default.

Properties

This tab contains options for formatting the size of the object, as well as the underlying R code used to create the visualization, and the JavaScript code use to customize the Object Inspector itself (see Object Inspector for more details about these options). Additional options are available by editing the code.

Chart

This tab contain options for formatting the text and graphical elements in the chart. It is organised into groups for Correlation (panels in the upper-right triangle), Scatterplots (panels in the lower-left triangle) and Histograms (panels along the diagonal).

Acknowledgements

Uses the R package weights.

Code

var heading_text = "Scatterplot Matrix"; 
if (!!form.setObjectInspectorTitle)
    form.setObjectInspectorTitle(heading_text, "Scatterplot Matrices");
else 
    form.setHeading(heading_text);

form.dropBox({name: "formInput", label: "Variables to plot",
    types: ["V:numeric, categorical, ordered categorical"],
    multi: true, min_inputs: 2, height: 8});
form.checkBox({label: "Variable names", name: "formNames", default_value: false, prompt: "Display names instead of labels"});
form.comboBox({label: "Missing data", 
    alternatives: ["Error if missing data", "Exclude cases with missing data", "Use partial data"], 
    name: "formMissing", default_value: "Use partial data",
    prompt: "Options for handling cases with missing data"});
qformLine = form.comboBox({label: "Fitted line",
            alternatives: ["None", "Straight", "LOESS"],
            name: "formLine", 
            default_value: "None", prompt: "Draw a fitted line or curve"});
qformMods = form.comboBox({label: "Scatter point modifications",
            alternatives: ["None", "Jitter", "Enlarge points with multiple observations"],
            name: "formPointMods",
            default_value: "Enlarge points with multiple observations",
            prompt: "Options for dealing with overlapping points"})

form.page("Chart");
form.group("Font");
font_families = !!Q.GetAvailableFontNames ? Q.GetAvailableFontNames() : ["Arial", "Arial Black", "Century Gothic", "Comic Sans MS",
                 "Courier New", "Georgia", "Impact", "Open Sans", "Tahoma", "Times New Roman", "Trebuchet MS", "Verdana"];
qGlobalFontFamily = form.comboBox({name: "formGlobalFontFamily", label: "Global font family", alternatives: font_families, default_value: "Open Sans", editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."}).getValue();
    qGlobalFontColor = form.colorPicker({name: "formGlobalFontColor", label: "Global font color", default_value: "#444444"}).getValue();
    qGlobalFontUnit = form.comboBox({name: "formFontUnits", label: "Font units", default_value: "pt", alternatives: ["px", "pt"], prompt: "Specify font sizes in pt or px"}).getValue();

form.group("Correlation");
form.numericUpDown({name: "formCorrelationDecimals", label: "Number of decimals", default_value: 2});
form.colorPicker({name: "formCorrelationFontColor", label: "Correlation font color", default_value: qGlobalFontColor});
form.comboBox({name: "formCorrelationFontFamily", label: "Correlation font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
form.numericUpDown({name: "formCorrelationFontSize", label: "Correlation font size", default_value: 10});


form.group("Scatterplots");
if (qformLine.getValue() != "None")
{
    form.colorPicker({name: "formLineColor", label: "Fit line color", default_value: "#990000"});
    form.numericUpDown({name: "formLineOpacity", label: "Fit line opacity", default_value: 1.0, minimum: 0.0, maximum: 1.0, incrememt: 0.1});
    form.numericUpDown({name: "formLineWidth", label: "Fit line width", default_value: 2.0});
}
form.colorPicker({name: "formPointColor", label: "Marker color", default_value: "#5C9AD3"});
form.numericUpDown({name: "formPointOpacity", label: "Marker opacity", default_value: 0.4, minimum: 0.0, maximum: 1.0, increment: 0.1})
form.numericUpDown({name: "formPointSize", label: "Marker size", default_value : qformMods.getValue() == "Enlarge points with multiple observations" ? 10.0 : 3.0, prompt: "Maximum size of markers in pixels."});

form.group("Histograms");
form.colorPicker({name: "formHistColor", label: "Histogram color", default_value: "#5C9AD3"});
form.numericUpDown({name: "formHistOpacity", label: "Histogram opacity", default_value: 1.0, minimum: 0.0, maximum: 1.0, increment: 0.1})
form.colorPicker({name: "formLabelFontColor", label: "Label font color", default_value: qGlobalFontColor});
form.comboBox({name: "formLabelFontFamily", label: "Label font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
form.numericUpDown({name: "formLabelFontSize", label: "Label font size", default_value: 10});

form.group("Axis labels");
form.numericUpDown({name: "formTickDecimals", label: "Number of decimals", required: false});
form.colorPicker({name: "formTickFontColor", label: "Tick label font color", default_value: qGlobalFontColor});
form.comboBox({name: "formTickFontFamily", label: "Tick label font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
form.numericUpDown({name: "formTickFontSize", label: "Tick label font size", default_value: 9});


form.group("Panels");
qformPanelBorder = form.checkBox({name: "formPanelBorderShow", label: "Show border around each panel", default_value: true});
if (qformPanelBorder.getValue())
{
    form.colorPicker({name: "formPanelBorderColor", label: "Border color", default_value: "#BBBBBB"});
    form.numericUpDown({name: "formPanelBorderWidth", label: "Border width", default_value: 1, minimum: 1});
}
form.numericUpDown({name: "formPanelGap", label: "Gap between panels", default_value: 0.01, increment: 0.01, minimum: 0.0, maximum: 0.25, prompt: "Space between panels as a proportion of the graphic size"});
form.colorPicker({name: "formPanelFillColor", label: "Fill color of panels", default_value: "transparent"});
form.numericUpDown({name: "formPanelFillOpacity", label: "Opacity of fill color", default_value: 1.0, minimum: 0.0, maximum: 1.0, increment: 0.1});

form.group("Title");
function isEmptyString(x) { return (x == undefined || x == null || x == "") }
qTitle = form.textBox({name: "formTitle", label: "Title", required: false});
if (!isEmptyString(qTitle.getValue()))
{
    form.colorPicker({name: "formTitleFontColor", label: "Title font color", default_value: qGlobalFontColor});
    form.comboBox({name: "formTitleFontFamily", label: "Title font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
    form.numericUpDown({name: "formTitleFontSize", label: "Title font size", default_value: 12});
}

qSubtitle = form.textBox({name: "formSubtitle", label: "Subtitle", required: false})
if (!isEmptyString(qSubtitle.getValue()))
{
    form.colorPicker({name: "formSubtitleFontColor", label: "Subtitle font color", default_value: qGlobalFontColor});
    form.comboBox({name: "formSubtitleFontFamily", label: "Subtitle font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
    form.numericUpDown({name: "formSubtitleFontSize", label: "Subtitle font size", default_value: 8});
}

form.group("Hovertext");
form.comboBox({name: "formHoverTextFontFamily", label: "Hovertext label font family", alternatives: font_families, default_value: qGlobalFontFamily, editable: true, prompt: "Select the font to use. You can also type the name of a font directly (including custom fonts)."});
form.numericUpDown({name: "formHoverTextFontSize", label: "Hovertext label font size", default_value: 9});

form.group("Background");
form.colorPicker({name: "formBgFillColor", label: "Fill color of background", default_value: "transparent"});
form.numericUpDown({name: "formBgFillOpacity", label: "Opacity of fill color", default_value: 1.0, minimum: 0.0, maximum: 1.0, increment: 0.1});
library(hash)
library(flipData)
library(flipFormat)
library(flipTransformations)
library(flipStandardCharts)

WarnIfVariablesSelectedFromMultipleDataSets()

dat <- AsNumeric(ProcessQVariables(QDataFrame(formInput)), binary = FALSE)
if (!formNames)
    names(dat) <- ExtractCommonPrefix(Labels(dat))$shortened.labels
wgt <- if (is.null(QCalibratedWeight)) {
    rep(1, nrow(dat))
} else {
    QCalibratedWeight
}
dat <- dat[QFilter, ]
wgt <- wgt[QFilter]

processed.data <- if (formMissing == "Error if missing data") {
    ErrorIfMissingDataFound(dat)
} else if (formMissing == "Exclude cases with missing data") {
    RemoveCasesWithAnyNA(dat)
} else if (formMissing == "Use partial data") {
    RemoveCasesWithAllNA(dat)
} else
    stop(c("Option not handled:", formMissing))
wgt <- wgt[row.names(dat) %in% rownames(processed.data)]

font.sc <- if (formFontUnits == "px") 1.0 else 1.333
ScatterplotMatrix(processed.data, weights = wgt, seed = 123,
    modifications = formPointMods,
    fit.type = formLine,
    fit.line.width = get0("formLineWidth"),
    fit.line.color = get0("formLineColor"),
    fit.line.opacity = get0("formLineOpacity"),
    point.symbol = "circle",
    point.size = formPointSize,
    point.color = formPointColor,
    point.opacity = formPointOpacity,
    histogram.color = formHistColor,
    histogram.opacity = formHistOpacity,
    correlation.decimals = formCorrelationDecimals,
    background.fill.color = formBgFillColor,
    background.fill.opacity = formBgFillOpacity,
    charting.area.fill.color = formPanelFillColor,
    charting.area.fill.opacity = formPanelFillOpacity,
    global.font.family = formGlobalFontFamily,
    global.font.color = formGlobalFontColor,
    label.font.family = formLabelFontFamily,
    label.font.color = formLabelFontColor,
    label.font.size = formLabelFontSize * font.sc,
    correlation.font.family = formCorrelationFontFamily,
    correlation.font.color = formCorrelationFontColor,
    correlation.font.size = formCorrelationFontSize * font.sc,
    tick.font.family = formTickFontColor,
    tick.font.color = formTickFontColor,
    tick.font.size = formTickFontSize * font.sc,
    tick.length = 3,
    tick.format = paste0(".", formTickDecimals, "f"),
    title = formTitle,
    title.font.family = get0("formTitleFontFamily"),
    title.font.color = get0("formTitleFontColor"),
    title.font.size = get0("formTitleFontSize") * font.sc,
    subtitle = formSubtitle,
    subtitle.font.family = get0("formSubtitleFontFamily"),
    subtitle.font.color = get0("formSubtitleFontColor"),
    subtitle.font.size = get0("formSubtitleFontSize") * font.sc,
    hovertext.font.family = formHoverTextFontFamily,
    hovertext.font.size = formHoverTextFontSize * font.sc,
    panel.outline = formPanelBorderShow,
    panel.line.width = get0("formPanelBorderWidth"),
    panel.line.color = get0("formPanelBorderColor"),
    panel.gap = formPanelGap,
    # Some extra parameters, not exposed
    panel.extend = 0.1,
    margin.left = NULL,
    margin.right = NULL,
    margin.top = NULL,
    margin.bottom = NULL,
    margin.autoexpand = TRUE,
    modebar.show = FALSE,
    tooltip.show = TRUE,
    zoom.enable = FALSE)