Skip to content

rewrite scatterplotmatrix so it uses patchwork#986

Merged
m7pr merged 34 commits into
mainfrom
patchwork-scatterplotmatrix
May 8, 2026
Merged

rewrite scatterplotmatrix so it uses patchwork#986
m7pr merged 34 commits into
mainfrom
patchwork-scatterplotmatrix

Conversation

@m7pr

@m7pr m7pr commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Part of

Satisfies last comment from 2025

Alternative to

This PR rewrite scatterplotmatrix so it uses patchwork

Coe do generate plots
library(ggplot2)
library(patchwork)
library(dplyr)

set.seed(42)
n <- 200
demo_data <- data.frame(
  AGE = rnorm(n, mean = 55, sd = 12),
  BMRKR1 = rlnorm(n, meanlog = 1.5, sdlog = 0.8),
  AVAL = rnorm(n, mean = 100, sd = 25),
  BMRKR2 = sample(c("LOW", "MEDIUM", "HIGH"), n, replace = TRUE, prob = c(0.3, 0.4, 0.3))
) %>%
  mutate(BMRKR2 = factor(BMRKR2, levels = c("LOW", "MEDIUM", "HIGH")))

demo_data$AGE[sample(n, 10)] <- NA
demo_data$BMRKR1[sample(n, 5)] <- NA

build_scatterplot_matrix <- function(data, varnames, alpha = 0.5, size = 1.5,
                                     add_cor = FALSE, cor_method = "pearson",
                                     cor_use = "pairwise.complete.obs") {
  col_names <- names(data)
  n_vars <- length(col_names)
  plot_list <- list()

  for (i in seq_len(n_vars)) {
    for (j in seq_len(n_vars)) {
      vi <- col_names[i]
      vj <- col_names[j]

      if (i == j) {
        if (is.numeric(data[[vi]])) {
          p <- ggplot(data, aes(x = .data[[vi]])) +
            geom_density(fill = "steelblue", alpha = 0.5) +
            labs(x = NULL, y = NULL) +
            ggtitle(varnames[i]) +
            theme_minimal() +
            theme(
              plot.title = element_text(hjust = 0.5, size = 9, face = "bold"),
              axis.text = element_text(size = 7)
            )
        } else {
          p <- ggplot(data, aes(x = .data[[vi]])) +
            geom_bar(fill = "steelblue", alpha = 0.5) +
            labs(x = NULL, y = NULL) +
            ggtitle(varnames[i]) +
            theme_minimal() +
            theme(
              plot.title = element_text(hjust = 0.5, size = 9, face = "bold"),
              axis.text = element_text(size = 7),
              axis.text.x = element_text(angle = 45, hjust = 1)
            )
        }
      } else if (add_cor && i < j) {
        if (is.numeric(data[[vi]]) && is.numeric(data[[vj]])) {
          cor_val <- tryCatch(
            cor(data[[vi]], data[[vj]], method = cor_method, use = cor_use),
            error = function(e) NA_real_
          )
          cor_label <- if (is.na(cor_val)) "NA" else sprintf("%.3f", cor_val)
          cor_size <- max(3, abs(cor_val) * 8 + 3)
          cor_color <- if (is.na(cor_val)) "grey50" else if (cor_val > 0) "firebrick" else "steelblue"
        } else {
          cor_label <- "-"
          cor_size <- 4
          cor_color <- "grey50"
        }
        p <- ggplot() +
          annotate("text", x = 0.5, y = 0.5, label = cor_label,
                   size = cor_size, fontface = "bold", color = cor_color) +
          xlim(0, 1) + ylim(0, 1) +
          theme_void()
      } else {
        if (is.numeric(data[[vj]]) && is.numeric(data[[vi]])) {
          p <- ggplot(data, aes(x = .data[[vj]], y = .data[[vi]])) +
            geom_point(alpha = alpha, size = size, color = "steelblue") +
            labs(x = NULL, y = NULL) +
            theme_minimal() +
            theme(axis.text = element_text(size = 7))
        } else if (is.factor(data[[vj]]) && is.numeric(data[[vi]])) {
          p <- ggplot(data, aes(x = .data[[vj]], y = .data[[vi]])) +
            geom_boxplot(fill = "steelblue", alpha = 0.5) +
            labs(x = NULL, y = NULL) +
            theme_minimal() +
            theme(axis.text = element_text(size = 7),
                  axis.text.x = element_text(angle = 45, hjust = 1))
        } else if (is.numeric(data[[vj]]) && is.factor(data[[vi]])) {
          p <- ggplot(data, aes(x = .data[[vi]], y = .data[[vj]])) +
            geom_boxplot(fill = "steelblue", alpha = 0.5) +
            labs(x = NULL, y = NULL) +
            theme_minimal() +
            theme(axis.text = element_text(size = 7),
                  axis.text.x = element_text(angle = 45, hjust = 1)) +
            coord_flip()
        } else {
          p <- ggplot(data, aes(x = .data[[vj]], fill = .data[[vi]])) +
            geom_bar(position = "dodge", alpha = 0.5) +
            labs(x = NULL, y = NULL, fill = NULL) +
            theme_minimal() +
            theme(axis.text = element_text(size = 7),
                  axis.text.x = element_text(angle = 45, hjust = 1),
                  legend.position = "none")
        }
      }
      plot_list[[(i - 1) * n_vars + j]] <- p
    }
  }
  wrap_plots(plot_list, ncol = n_vars, nrow = n_vars)
}

varnames <- c("Age", "Biomarker 1", "Analysis Value", "Biomarker 2")

plot_with_cor <- build_scatterplot_matrix(
  demo_data, varnames, add_cor = TRUE, cor_method = "pearson"
) + plot_annotation(title = "With Correlation (Pearson)")

plot_without_cor <- build_scatterplot_matrix(
  demo_data, varnames, add_cor = FALSE
) + plot_annotation(title = "Without Correlation")

plot_spearman <- build_scatterplot_matrix(
  demo_data, varnames, add_cor = TRUE, cor_method = "spearman"
) + plot_annotation(title = "With Correlation (Spearman)")

numeric_data <- demo_data %>% select(AGE, BMRKR1, AVAL)
plot_numeric_only <- build_scatterplot_matrix(
  numeric_data, c("Age", "Biomarker 1", "Analysis Value"),
  add_cor = TRUE, cor_method = "pearson"
) + plot_annotation(title = "Numeric Only - Correlation Matrix Style")

output_dir <- file.path("dev", "demo_plots")
dir.create(output_dir, showWarnings = FALSE, recursive = TRUE)

ggsave(file.path(output_dir, "1_with_correlation_pearson.png"), plot_with_cor, width = 10, height = 10, dpi = 150)
ggsave(file.path(output_dir, "2_without_correlation.png"), plot_without_cor, width = 10, height = 10, dpi = 150)
ggsave(file.path(output_dir, "3_with_correlation_spearman.png"), plot_spearman, width = 10, height = 10, dpi = 150)
ggsave(file.path(output_dir, "4_numeric_only_correlation.png"), plot_numeric_only, width = 8, height = 8, dpi = 150)

1_with_correlation_pearson 2_without_correlation 3_with_correlation_spearman 4_numeric_only_correlation

@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Unit Tests Summary

    1 files   37 suites   4m 20s ⏱️
  684 tests 566 ✅ 118 💤 0 ❌
1 030 runs  912 ✅ 118 💤 0 ❌

Results for commit 45c1f58.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Unit Test Performance Difference

Test suite performance difference
Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
examples 💚 $5.22$ $-4.56$ $-1$ $+40$ $0$ $0$
scatterplotmatrix_get_stats 💀 $0.03$ $-0.03$ $-6$ $0$ $0$ $0$
shinytest2-tm_a_pca 💚 $225.26$ $-224.17$ $-38$ $+11$ $0$ $0$
shinytest2-tm_a_regression 💚 $90.43$ $-89.79$ $-24$ $+7$ $0$ $0$
shinytest2-tm_data_table 💚 $37.15$ $-36.77$ $-6$ $+4$ $0$ $0$
shinytest2-tm_file_viewer 💚 $45.40$ $-44.44$ $-9$ $+4$ $0$ $0$
shinytest2-tm_front_page 💚 $33.50$ $-33.06$ $-6$ $+3$ $0$ $0$
shinytest2-tm_g_association 💚 $47.42$ $-46.84$ $-9$ $+4$ $0$ $0$
shinytest2-tm_g_bivariate 💚 $102.01$ $-101.61$ $-40$ $+4$ $0$ $0$
shinytest2-tm_g_distribution 💚 $118.00$ $-117.62$ $-17$ $+3$ $0$ $0$
shinytest2-tm_g_response 💚 $48.64$ $-48.27$ $-13$ $+4$ $0$ $0$
shinytest2-tm_g_scatterplot 💚 $139.30$ $-138.83$ $-30$ $+5$ $0$ $0$
shinytest2-tm_g_scatterplotmatrix 💚 $45.70$ $-45.12$ $-5$ $+4$ $0$ $0$
shinytest2-tm_missing_data 💚 $68.66$ $-67.84$ $-18$ $+4$ $0$ $0$
shinytest2-tm_outliers 💚 $173.50$ $-172.49$ $-51$ $+10$ $0$ $0$
shinytest2-tm_t_crosstable 💚 $50.42$ $-49.67$ $-5$ $+4$ $0$ $0$
shinytest2-tm_variable_browser 💚 $99.05$ $-98.40$ $-17$ $+6$ $0$ $0$
tm_a_pca 💔 $15.25$ $+1.71$ $0$ $0$ $0$ $0$
tm_g_association 💔 $11.40$ $+2.14$ $0$ $0$ $0$ $0$
tm_g_bivariate 💔 $7.52$ $+1.20$ $0$ $0$ $0$ $0$
tm_g_scatterplotmatrix 💔 $1.31$ $+5.27$ $0$ $0$ $0$ $0$
tm_outliers 💔 $48.65$ $+4.36$ $0$ $0$ $0$ $0$
utils 💚 $13.67$ $-1.45$ $0$ $0$ $0$ $0$
variable_browser 💔 $64.50$ $+3.36$ $0$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
examples 💚 $1.99$ $-1.97$ example_add_facet_labels.Rd
examples 💀 $0.01$ $-0.01$ example_get_scatterplotmatrix_stats.Rd
scatterplotmatrix_get_stats 💀 $0.01$ $-0.01$ get_scatterplotmatrix_stats_x_y_character
scatterplotmatrix_get_stats 💀 $0.02$ $-0.02$ get_scatterplotmatrix_stats_x_y_numeric
shinytest2-tm_a_pca 💚 $16.14$ $-16.06$ e2e_tm_a_pca_Changing_output_encodings_for_plot_type_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $10.57$ $-10.49$ e2e_tm_a_pca_Changing_output_encodings_of_NA_action_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $73.85$ $-73.76$ e2e_tm_a_pca_Changing_output_encodings_of_font_size_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $34.35$ $-34.27$ e2e_tm_a_pca_Changing_output_encodings_of_plot_type_hides_and_shows_options.
shinytest2-tm_a_pca 💚 $15.41$ $-15.32$ e2e_tm_a_pca_Changing_output_encodings_of_standardization_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $11.35$ $-11.27$ e2e_tm_a_pca_Changing_output_encodings_of_tables_display_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $12.12$ $-12.03$ e2e_tm_a_pca_Changing_output_encodings_of_theme_does_not_generate_errors.
shinytest2-tm_a_pca 💚 $14.56$ $-14.47$ e2e_tm_a_pca_Color_by_columns_data_extract_must_be_from_non_selected_variable_set.
shinytest2-tm_a_pca 💚 $11.01$ $-10.91$ e2e_tm_a_pca_Eigenvector_table_should_have_data_extract_selection_Murder_Assault_on_header.
shinytest2-tm_a_pca 💚 $14.26$ $-14.17$ e2e_tm_a_pca_Eigenvector_table_should_have_data_extract_selection_Murder_UrbanPop_on_header.
shinytest2-tm_a_pca 💚 $11.64$ $-11.42$ e2e_tm_a_pca_Module_is_initialised_with_the_specified_defaults_in_function_call.
shinytest2-tm_a_regression 💚 $9.73$ $-9.62$ e2e_tm_a_regression_Data_extract_spec_elements_are_initialized_with_the_default_values_specified_by_response_and_regressor_arg.
shinytest2-tm_a_regression 💚 $9.65$ $-9.56$ e2e_tm_a_regression_Data_parameter_and_module_label_is_passed_properly.
shinytest2-tm_a_regression 💚 $14.34$ $-14.26$ e2e_tm_a_regression_Outlier_definition_and_label_are_visible_by_default.
shinytest2-tm_a_regression 💚 $9.82$ $-9.73$ e2e_tm_a_regression_Outlier_definition_and_label_have_default_values_and_label_text.
shinytest2-tm_a_regression 💚 $20.01$ $-19.92$ e2e_tm_a_regression_Plot_type_has_7_specific_choices_changing_choices_does_not_throw_errors.
shinytest2-tm_a_regression 💚 $11.66$ $-11.58$ e2e_tm_a_regression_Plot_type_is_set_properly.
shinytest2-tm_a_regression 💚 $15.22$ $-15.13$ e2e_tm_a_regression_Unchecking_display_outlier_hides_outlier_label_and_definition.
shinytest2-tm_data_table 💚 $8.35$ $-8.24$ e2e_tm_data_table_Initializes_without_errors
shinytest2-tm_data_table 💚 $8.34$ $-8.25$ e2e_tm_data_table_Verify_checkbox_displayed_over_data_table
shinytest2-tm_data_table 💚 $9.19$ $-9.09$ e2e_tm_data_table_Verify_default_variable_selection_and_set_new_selection
shinytest2-tm_data_table 💚 $11.28$ $-11.19$ e2e_tm_data_table_Verify_module_displays_data_table
shinytest2-tm_file_viewer 💚 $9.61$ $-9.33$ e2e_tm_file_viewer_Initializes_without_errors_and_shows_files_tree_specified_in_input_path_argument
shinytest2-tm_file_viewer 💚 $11.98$ $-11.75$ e2e_tm_file_viewer_Shows_selected_image_file
shinytest2-tm_file_viewer 💚 $11.84$ $-11.61$ e2e_tm_file_viewer_Shows_selected_text_file
shinytest2-tm_file_viewer 💚 $11.97$ $-11.74$ e2e_tm_file_viewer_Shows_selected_url
shinytest2-tm_front_page 💚 $8.09$ $-7.93$ e2e_tm_front_page_Initializes_without_errors_and_check_html_elements
shinytest2-tm_front_page 💚 $13.08$ $-12.93$ e2e_tm_front_page_Verify_the_module_displays_metadata
shinytest2-tm_front_page 💚 $12.33$ $-12.19$ e2e_tm_front_page_Verify_the_module_displays_tables
shinytest2-tm_g_association 💚 $13.21$ $-13.07$ e2e_tm_g_association_Check_and_set_default_values_for_radio_buttons.
shinytest2-tm_g_association 💚 $12.45$ $-12.30$ e2e_tm_g_association_Data_extract_spec_elements_are_initialized_with_the_default_values_specified_by_ref_and_vars_arguments.
shinytest2-tm_g_association 💚 $9.78$ $-9.64$ e2e_tm_g_association_Data_parameter_and_module_label_is_passed_properly.
shinytest2-tm_g_association 💚 $11.98$ $-11.83$ e2e_tm_g_association_Module_plot_is_visible.
shinytest2-tm_g_bivariate 💚 $24.37$ $-24.25$ e2e_tm_g_bivariate_Coloring_options_are_hidden_when_coloring_is_toggled_off.
shinytest2-tm_g_bivariate 💚 $28.54$ $-28.45$ e2e_tm_g_bivariate_Facetting_options_are_hidden_when_facet_is_toggled_off.
shinytest2-tm_g_bivariate 💚 $10.83$ $-10.73$ e2e_tm_g_bivariate_Module_is_initialised_with_the_specified_defaults.
shinytest2-tm_g_bivariate 💚 $38.27$ $-38.18$ e2e_tm_g_bivariate_Setting_encoding_inputs_produces_outputs_without_validation_errors.
shinytest2-tm_g_distribution 💚 $24.32$ $-24.10$ e2e_tm_g_distribution_Histogram_encoding_inputs_produce_output_without_validation_errors.
shinytest2-tm_g_distribution 💚 $78.00$ $-77.91$ e2e_tm_g_distribution_Module_is_initialised_with_the_specified_defaults.
shinytest2-tm_g_distribution 💚 $15.69$ $-15.61$ e2e_tm_g_distribution_QQ_plot_encoding_inputs_produce_output_without_validation_errors.
shinytest2-tm_g_response 💚 $10.27$ $-10.19$ e2e_tm_g_response_deselecting_response_produces_validation_error.
shinytest2-tm_g_response 💚 $10.06$ $-9.98$ e2e_tm_g_response_deselecting_x_produces_validation_error.
shinytest2-tm_g_response 💚 $18.45$ $-18.34$ e2e_tm_g_response_encoding_inputs_produce_output_without_validation_errors.
shinytest2-tm_g_response 💚 $9.86$ $-9.76$ e2e_tm_g_response_module_is_initialised_with_the_specified_defaults.
shinytest2-tm_g_scatterplot 💚 $13.57$ $-13.47$ e2e_tm_g_scatterplot_Base_for_the_log_transformation_can_be_applied.
shinytest2-tm_g_scatterplot 💚 $11.85$ $-11.77$ e2e_tm_g_scatterplot_Get_validation_error_when_facetting_with_the_same_row_col_variable.
shinytest2-tm_g_scatterplot 💚 $10.31$ $-10.22$ e2e_tm_g_scatterplot_Module_is_initialised_with_the_specified_defaults.
shinytest2-tm_g_scatterplot 💚 $89.45$ $-89.36$ e2e_tm_g_scatterplot_The_encoding_inputs_are_set_without_validation_errors.
shinytest2-tm_g_scatterplot 💚 $14.11$ $-14.02$ e2e_tm_g_scatterplot_The_log_transform_is_only_possible_for_positive_numeric_vars.
shinytest2-tm_g_scatterplotmatrix 💚 $13.50$ $-13.36$ e2e_tm_g_scatterplotmatrix_Change_plot_settings
shinytest2-tm_g_scatterplotmatrix 💚 $9.46$ $-9.30$ e2e_tm_g_scatterplotmatrix_Initializes_without_errors
shinytest2-tm_g_scatterplotmatrix 💚 $11.11$ $-10.98$ e2e_tm_g_scatterplotmatrix_Verify_default_values_and_settings_data_extracts_for_data_selection
shinytest2-tm_g_scatterplotmatrix 💚 $11.63$ $-11.48$ e2e_tm_g_scatterplotmatrix_Verify_module_displays_data_table
shinytest2-tm_missing_data 💚 $19.62$ $-19.42$ e2e_tm_missing_data_Check_default_settings_and_visibility_of_the_combinations_graph_and_encodings
shinytest2-tm_missing_data 💚 $19.45$ $-19.24$ e2e_tm_missing_data_Default_settings_and_visibility_of_the_summary_graph
shinytest2-tm_missing_data 💚 $10.47$ $-10.26$ e2e_tm_missing_data_Initializes_without_errors
shinytest2-tm_missing_data 💚 $19.11$ $-18.91$ e2e_tm_missing_data_Validate_functionality_and_UI_response_for_By_Variable_Levels_
shinytest2-tm_outliers 💚 $16.52$ $-16.41$ e2e_tm_outliers_Data_extract_spec_elements_are_initialized_with_the_default_values_specified_by_outlier_var_and_categorical_var_argument.
shinytest2-tm_outliers 💚 $11.97$ $-11.87$ e2e_tm_outliers_Data_parameter_and_module_label_is_passed_properly.
shinytest2-tm_outliers 💚 $16.25$ $-16.15$ e2e_tm_outliers_Default_radio_buttons_are_set_properly.
shinytest2-tm_outliers 💚 $11.75$ $-11.65$ e2e_tm_outliers_Method_parameters_are_set_properly.
shinytest2-tm_outliers 💚 $11.96$ $-11.86$ e2e_tm_outliers_Module_is_divided_into_3_tabs.
shinytest2-tm_outliers 💚 $33.47$ $-33.37$ e2e_tm_outliers_Outlier_definition_text_and_range_are_displayed_properly_depending_on_method.
shinytest2-tm_outliers 💚 $15.92$ $-15.82$ e2e_tm_outliers_Outlier_table_is_displayed_with_proper_content.
shinytest2-tm_outliers 💚 $18.20$ $-18.11$ e2e_tm_outliers_Outliers_summary_table_is_displayed_with_proper_content.
shinytest2-tm_outliers 💚 $14.04$ $-13.94$ e2e_tm_outliers_Plot_type_is_correctly_set_by_default_and_has_appropriate_possible_options.
shinytest2-tm_outliers 💚 $23.43$ $-23.33$ e2e_tm_outliers_Plot_type_is_hidden_when_Boxplot_tab_is_not_selected.
shinytest2-tm_t_crosstable 💚 $15.27$ $-15.15$ e2e_tm_t_crosstable_Change_plot_settings
shinytest2-tm_t_crosstable 💚 $10.12$ $-9.75$ e2e_tm_t_crosstable_Initializes_without_errors
shinytest2-tm_t_crosstable 💚 $12.88$ $-12.76$ e2e_tm_t_crosstable_Verify_default_values_and_settings_data_extracts_for_data_selection
shinytest2-tm_t_crosstable 💚 $12.15$ $-12.01$ e2e_tm_t_crosstable_Verify_module_displays_data_table
shinytest2-tm_variable_browser 💚 $14.74$ $-14.63$ e2e_tm_variable_browser_Selecting_treat_variable_as_factor_changes_the_table_headers.
shinytest2-tm_variable_browser 💚 $16.55$ $-16.44$ e2e_tm_variable_browser_changing_display_density_encoding_doesn_t_show_errors.
shinytest2-tm_variable_browser 💚 $19.55$ $-19.45$ e2e_tm_variable_browser_changing_outlier_definition_encoding_doesn_t_show_errors.
shinytest2-tm_variable_browser 💚 $22.20$ $-22.09$ e2e_tm_variable_browser_changing_plot_setting_encodings_doesn_t_show_errors.
shinytest2-tm_variable_browser 💚 $13.19$ $-13.07$ e2e_tm_variable_browser_content_is_displayed_correctly.
shinytest2-tm_variable_browser 💚 $12.82$ $-12.72$ e2e_tm_variable_browser_selection_of_categorical_variable_has_a_table_with_level_header.
tm_g_scatterplotmatrix 💔 $0.61$ $+3.17$ tm_g_scatterplotmatrix_module_server_behavior_server_function_executes_successfully_through_module_interface
tm_g_scatterplotmatrix 💔 $0.60$ $+1.96$ tm_g_scatterplotmatrix_module_server_behavior_server_function_generates_scatterplot_matrix_with_two_variables
tm_outliers 💔 $6.23$ $+1.11$ tm_outliers_module_server_behavior_server_function_handles_different_ggtheme_options_through_module_interface
utils 💚 $3.17$ $-1.09$ Module_with_decorators_Default_and_one_decorator_to_one_object_executes_successfully
variable_browser 💔 $11.03$ $+1.86$ UI_switches_and_controls_server_handles_different_outlier_definition_thresholds

Results for commit ad2bb09

♻️ This comment has been updated with latest results.

@donyunardi donyunardi requested review from a team and removed request for donyunardi March 6, 2026 00:48

@gogonzo gogonzo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch needs a proper code reducing.

Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
@gogonzo gogonzo self-assigned this Mar 6, 2026

@llrs-roche llrs-roche left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plots generated with lots of duplicate code. I think there are several ways to simplify them:

  1. Reuse a base plot and then update it for each specific purpose.
  2. Apply the theme and general characteristics after the plots are wrapped by patchwork ( use the right operator to apply to all plots).

Sorry I didn't assign myself and we have duplicated efforts but I agree with the previous review

I ran the example and text is too small to read:

image

Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated
@github-actions

github-actions Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

badge

Code Coverage Summary

Filename                      Stmts    Miss  Cover    Missing
--------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
R/geom_mosaic.R                  73       0  100.00%
R/tm_a_pca.R                    852       0  100.00%
R/tm_a_regression.R             750     391  47.87%   496-523, 530-533, 540-541, 545-555, 559, 563-575, 580-595, 600-622, 625-633, 637-665, 670-680, 683-709, 716-740, 743-768, 775-782, 785-811, 818-846, 849-874, 881-900, 903-929, 936-950, 953-979, 1004, 1008
R/tm_data_table.R               204       8  96.08%   110, 115-120, 330
R/tm_file_viewer.R              172      50  70.93%   141-152, 156-163, 165-167, 172-182, 184, 204, 229-235, 237-238, 240, 244-250
R/tm_front_page.R               143       0  100.00%
R/tm_g_association.R            320      72  77.50%   226-294, 319, 325, 474, 488
R/tm_g_bivariate.R              672     196  70.83%   332-471, 505, 511-514, 585, 590, 595, 616-618, 655-658, 668-682, 684-685, 712-721, 763, 829, 940, 987, 989, 991, 998-1008
R/tm_g_distribution.R          1115      60  94.62%   418-426, 432-435, 474-475, 477, 479, 488, 490, 494-497, 501-504, 507, 519-520, 575, 586, 600, 895, 1082-1086, 1155-1159, 1161-1167, 1298-1301, 1319-1321, 1407-1408
R/tm_g_response.R               345      87  74.78%   184-185, 192, 198, 259-325, 348-352, 425, 430, 447-453, 531, 537, 550
R/tm_g_scatterplot.R            709     259  63.47%   359-501, 534-537, 575, 624, 636, 650, 667, 672, 698-711, 787-798, 837, 845-882, 894-896, 906-912, 919-921, 932-940, 942-943, 945, 949, 983-996, 1040, 1060
R/tm_g_scatterplotmatrix.R      336     145  56.85%   262-360, 383, 386, 441-447, 461-464, 466, 489-492, 504, 507-519, 525-526, 532-534, 586-594
R/tm_gtsummary.R                148       0  100.00%
R/tm_missing_data.R            1180     167  85.85%   129, 488, 494, 507, 512, 532-538, 547-553, 620-635, 676, 680, 721, 739-746, 771, 787-790, 848-927, 931-933, 964-971, 1104, 1241, 1280, 1332-1334, 1344-1364, 1472, 1474, 1477-1478
R/tm_outliers.R                1029     186  81.92%   400, 428, 438-439, 441-442, 517-531, 533, 613, 616, 654-706, 709-747, 759, 790, 809, 812-827, 888-891, 965-993, 1117, 1220-1223, 1227, 1230-1233, 1239-1248, 1250, 1254-1263, 1266-1267, 1269
R/tm_rmarkdown.R                159       0  100.00%
R/tm_t_crosstable.R             263      56  78.71%   227-269, 292-293, 309, 318, 425, 438-447
R/tm_variable_browser.R         887      27  96.96%   395, 597, 812-826, 956, 984, 986, 1058-1059, 1067, 1165, 1246, 1278, 1310
R/utils.R                       148      15  89.86%   146, 177, 227, 288-291, 300-306, 314, 350, 353
R/zzz.R                           2       2  0.00%    2-3
TOTAL                          9507    1721  81.90%

Diff against main

Filename                      Stmts    Miss  Cover
--------------------------  -------  ------  -------
R/tm_a_regression.R              -1       0  -0.07%
R/tm_g_scatterplotmatrix.R      +64     +35  -2.71%
TOTAL                           +63     +35  -0.25%

Results for commit: 45c1f58

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

@m7pr m7pr marked this pull request as draft March 9, 2026 08:28
@m7pr

m7pr commented Mar 9, 2026

Copy link
Copy Markdown
Contributor Author

Hey @gogonzo and @llrs-roche - thanks for the review. I mainly aimed to get a quick prototype of the output, so we could compare different approaches. Will work on improving the PR and making it more polished and production-ready.
Until then I will mark this one as draft.

@gogonzo

gogonzo commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

I just run an app and:

  1. Selected 5 variables. Visuals need serious improvements:
image
  1. Loop to make k-ggplots also impacts the performance. I selected 10 variables and It took around 10 seconds before I saw it rendered.

  2. R code is looooong

Skärmavbild 2026-03-09 kl  12 27 17

IMO This visualization is a candidate for a separate package to optimize geom creations.

Comment thread R/tm_a_regression.R
Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R
Comment thread R/tm_g_scatterplotmatrix.R
@m7pr m7pr requested review from gogonzo and llrs-roche March 12, 2026 11:05
@m7pr

m7pr commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

Hey @gogonzo last touches on the labels. I think we should just show the labels at the outside of the matrix for the categorical variables (no labels where red lines, labels only where the blue line is). This saves a lot of space. Also the labels for the categorical variables are trimmed, so they don't take the whole space of the plot

image

I would appreciate your opinion in general on the PR. I think it's ready in it's current state. The code being long in show r code could be tackled as a separate extension to teal via styler pacakge.

Signed-off-by: Marcin <133694481+m7pr@users.noreply.github.com>
@donyunardi donyunardi linked an issue Apr 21, 2026 that may be closed by this pull request
3 tasks

@gogonzo gogonzo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Please remove debounce - details in one of the comments.

@donyunardi @m7pr I like the visuals, I think previous version was almost useless.

Comment thread R/tm_g_scatterplotmatrix.R Outdated
Comment thread R/tm_g_scatterplotmatrix.R Outdated

@gogonzo gogonzo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I hope it doesn't destroy too much in picks PR

@m7pr

m7pr commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Hey @donyunardi @gogonzo about this
#986 (comment)
maybe we can parametrize so module has the max tiles as a parameter?

@donyunardi

donyunardi commented May 7, 2026

Copy link
Copy Markdown
Contributor

Hey @donyunardi @gogonzo about this #986 (comment) maybe we can parametrize so module has the max tiles as a parameter?

I think parameterize makes sense to me. We can explain in the documentation why we recommend 5 and it's up to app developer to decide what would be the best for the user based on the data for this module.

Another option is do a soft warning in the UI instead of hard stop when someone choose more than 5.

I like the first option better.

@m7pr

m7pr commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

Alrighty, so I'll add a new parameter, and will merge
Or we can discuss how to handle that with the teal.picks migration

@m7pr m7pr enabled auto-merge (squash) May 8, 2026 10:16
@m7pr m7pr merged commit 3eec3ed into main May 8, 2026
26 of 28 checks passed
@m7pr m7pr deleted the patchwork-scatterplotmatrix branch May 8, 2026 10:27
@github-actions github-actions Bot locked and limited conversation to collaborators May 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UAT Exploratory App: scatterplot matrix, correlation NA

4 participants