diff --git a/examples/multi-panel/Python/facet_matplotlib.py b/examples/multi-panel/Python/facet_matplotlib.py new file mode 100644 index 000000000..123fd2366 --- /dev/null +++ b/examples/multi-panel/Python/facet_matplotlib.py @@ -0,0 +1,39 @@ +import matplotlib.pyplot as plt +import seaborn as sns + +# Load the penguins dataset using seaborn +penguins = sns.load_dataset("penguins") + +# Get unique species and sexes +species = penguins["species"].dropna().unique() +sexes = penguins["sex"].dropna().unique() + +# Create a figure and a grid of subplots +fig, axes = plt.subplots( + nrows=len(species), ncols=len(sexes), figsize=(12, 8), sharex=True, sharey=True +) + +# Set a global title for the figure +fig.suptitle("Penguin Bill Dimensions by Species and Sex", fontsize=16) + +# Loop through species and sexes to create each subplot +for i, sp in enumerate(species): + for j, sex in enumerate(sexes): + ax = axes[i, j] + subset = penguins[(penguins["species"] == sp) & (penguins["sex"] == sex)] + ax.scatter(subset["bill_length_mm"], subset["bill_depth_mm"]) + + # Set panel-specific titles + ax.set_title(f"{sp} - {sex}", fontsize=12) + + # Set x and y labels for the leftmost and bottom plots only + if i == len(species) - 1: + ax.set_xlabel("Bill Length (mm)") + if j == 0: + ax.set_ylabel("Bill Depth (mm)") + +# Adjust layout to prevent overlap +plt.tight_layout(rect=[0, 0, 1, 0.95]) # Adjust rect to make space for the global title + +# Show the plot +plt.show() diff --git a/examples/multi-panel/Python/facet_seaborn.py b/examples/multi-panel/Python/facet_seaborn.py new file mode 100644 index 000000000..b40c86da9 --- /dev/null +++ b/examples/multi-panel/Python/facet_seaborn.py @@ -0,0 +1,12 @@ +import matplotlib.pyplot as plt +import seaborn as sns + +penguins = sns.load_dataset("penguins") + +g = sns.FacetGrid(penguins, row="species", col="sex") +g.map(sns.scatterplot, "bill_length_mm", "bill_depth_mm") +g.fig.suptitle("Penguin Bill Dimensions by Species and Sex", fontsize=16) +g.fig.subplots_adjust(top=0.9) # Adjust subplots to fit the title +g.set_axis_labels("Bill Length (mm)", "Bill Depth (mm)") +g.set_titles(row_template="{row_name}", col_template="{col_name}") +plt.show() diff --git a/examples/multi-panel/R/facet_ggplot.r b/examples/multi-panel/R/facet_ggplot.r new file mode 100644 index 000000000..1b000cc55 --- /dev/null +++ b/examples/multi-panel/R/facet_ggplot.r @@ -0,0 +1,65 @@ +# Load the required libraries +library(ggplot2) +library(palmerpenguins) +library(svglite) + +# Load the penguins dataset +data("penguins") +penguins <- na.omit(penguins) + +# Create a ggplot +p <- ggplot(penguins, aes(x = bill_length_mm, y = bill_depth_mm)) + + geom_point() + + facet_grid(species ~ sex) + + labs( + title = "Penguin Bill Dimensions by Species and Sex", + x = "Bill Length (mm)", + y = "Bill Depth (mm)" + ) + + theme( + plot.title = element_text(size = 16, hjust = 0.5), + strip.text = element_text(size = 12), + axis.title = element_text(size = 12) + ) + +# Save the plot as an SVG file using ggsave and svglite +ggsave("multi_panel.svg", plot = p, device = svglite, width = 10, height = 8) + +# Extract raw data used for plotting per panel +plot_data <- ggplot_build(p)$data[[1]] +# Split the data by panel +plot_data_split <- split(plot_data, plot_data$PANEL) + +# Save each panel data as a separate data frame object +panel_data_list <- lapply(names(plot_data_split), function(panel) { + panel_data <- plot_data_split[[panel]] + assign(paste0("panel_data_", panel), panel_data, envir = .GlobalEnv) + return(panel_data) +}) + +# Assign names to the list elements for easier reference +names(panel_data_list) <- names(plot_data_split) + +# Load the required library for JSON +library(jsonlite) + +# Save each panel data as a JSON file containing only x and y variables +lapply(names(panel_data_list), function(panel) { + panel_data <- panel_data_list[[panel]][, c("x", "y")] + json_file <- paste0("panel_data_", panel, ".json") + write_json(panel_data, json_file) +}) + + + +# Extract the layout information to get the panel titles +layout_info <- ggplot_build(p)$layout$layout + +# Create a data frame that maps panel numbers to species and sex +panel_mapping <- data.frame( + PANEL = layout_info$PANEL, + species = layout_info$species, + sex = layout_info$sex +) + +print(panel_mapping) diff --git a/examples/multi-panel/multi_panel.svg b/examples/multi-panel/multi_panel.svg new file mode 100644 index 000000000..92e3ae4cf --- /dev/null +++ b/examples/multi-panel/multi_panel.svg @@ -0,0 +1,736 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + female + + + + + + + + + + + male + + + + + + + + + + + Adelie + + + + + + + + + + + Chinstrap + + + + + + + + + + + Gentoo + + + + + + 40 + 50 + 60 + + + + 40 + 50 + 60 + 15.0 + 17.5 + 20.0 + + + + 15.0 + 17.5 + 20.0 + + + + 15.0 + 17.5 + 20.0 + + + + Bill Length (mm) + Bill Depth (mm) + Penguin Bill Dimensions by Species and Sex + + \ No newline at end of file diff --git a/examples/multi-panel/multi_panel_schema.json b/examples/multi-panel/multi_panel_schema.json new file mode 100644 index 000000000..fce80f4b9 --- /dev/null +++ b/examples/multi-panel/multi_panel_schema.json @@ -0,0 +1,448 @@ +{ + "id": "container-figure-id", + "selector": "", + "layout": { + "rows": 3, + "columns": 2 + }, + "title": "Penguin Bill Dimensions by Species and Sex", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "panels": [ + { + "id": "panel-01", + "selector": "", + "type": "point", + "title": "Adelie - Female", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 39.5, "y": 17.4 }, + { "x": 40.3, "y": 18 }, + { "x": 36.7, "y": 19.3 }, + { "x": 38.9, "y": 17.8 }, + { "x": 41.1, "y": 17.6 }, + { "x": 36.6, "y": 17.8 }, + { "x": 38.7, "y": 19 }, + { "x": 34.4, "y": 18.4 }, + { "x": 37.8, "y": 18.3 }, + { "x": 35.9, "y": 19.2 }, + { "x": 35.3, "y": 18.9 }, + { "x": 40.5, "y": 17.9 }, + { "x": 37.9, "y": 18.6 }, + { "x": 39.5, "y": 16.7 }, + { "x": 39.5, "y": 17.8 }, + { "x": 36.4, "y": 17 }, + { "x": 42.2, "y": 18.5 }, + { "x": 37.6, "y": 19.3 }, + { "x": 36.5, "y": 18 }, + { "x": 36, "y": 18.5 }, + { "x": 37, "y": 16.9 }, + { "x": 36, "y": 17.9 }, + { "x": 39.6, "y": 17.7 }, + { "x": 35, "y": 17.9 }, + { "x": 34.5, "y": 18.1 }, + { "x": 39, "y": 17.5 }, + { "x": 36.5, "y": 16.6 }, + { "x": 35.7, "y": 16.9 }, + { "x": 37.6, "y": 17 }, + { "x": 36.4, "y": 17.1 }, + { "x": 35.5, "y": 16.2 }, + { "x": 35.9, "y": 16.6 }, + { "x": 33.5, "y": 19 }, + { "x": 39.6, "y": 17.2 }, + { "x": 35.5, "y": 17.5 }, + { "x": 40.9, "y": 16.8 }, + { "x": 36.2, "y": 16.1 }, + { "x": 34.6, "y": 17.2 }, + { "x": 36.7, "y": 18.8 }, + { "x": 37.3, "y": 17.8 }, + { "x": 36.9, "y": 18.6 }, + { "x": 38.9, "y": 18.8 }, + { "x": 35.7, "y": 18 }, + { "x": 34, "y": 17.1 }, + { "x": 36.2, "y": 17.3 }, + { "x": 38.1, "y": 18.6 }, + { "x": 33.1, "y": 16.1 }, + { "x": 35, "y": 17.9 }, + { "x": 37.7, "y": 16 }, + { "x": 37.9, "y": 18.6 }, + { "x": 38.6, "y": 17.2 }, + { "x": 38.1, "y": 17 }, + { "x": 38.1, "y": 16.5 }, + { "x": 39.7, "y": 17.7 }, + { "x": 39.6, "y": 20.7 }, + { "x": 38.6, "y": 17 }, + { "x": 35.7, "y": 17 }, + { "x": 36.2, "y": 17.2 }, + { "x": 40.2, "y": 17 }, + { "x": 35.2, "y": 15.9 }, + { "x": 38.8, "y": 17.6 }, + { "x": 39, "y": 17.1 }, + { "x": 38.5, "y": 17.9 }, + { "x": 36.8, "y": 18.5 }, + { "x": 38.1, "y": 17.6 }, + { "x": 35.6, "y": 17.5 }, + { "x": 37, "y": 16.5 }, + { "x": 40.2, "y": 17.1 }, + { "x": 32.1, "y": 15.5 }, + { "x": 37.3, "y": 16.8 }, + { "x": 36.6, "y": 18.4 }, + { "x": 36, "y": 17.8 }, + { "x": 36, "y": 17.1 } + ] + }, + { + "id": "panel-02", + "selector": "", + "type": "point", + "title": "Adelie - Male", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 39.1, "y": 18.7 }, + { "x": 39.3, "y": 20.6 }, + { "x": 39.2, "y": 19.6 }, + { "x": 38.6, "y": 21.2 }, + { "x": 34.6, "y": 21.1 }, + { "x": 42.5, "y": 20.7 }, + { "x": 46, "y": 21.5 }, + { "x": 37.7, "y": 18.7 }, + { "x": 38.2, "y": 18.1 }, + { "x": 38.8, "y": 17.2 }, + { "x": 40.6, "y": 18.6 }, + { "x": 40.5, "y": 18.9 }, + { "x": 37.2, "y": 18.1 }, + { "x": 40.9, "y": 18.9 }, + { "x": 39.2, "y": 21.1 }, + { "x": 38.8, "y": 20 }, + { "x": 39.8, "y": 19.1 }, + { "x": 40.8, "y": 18.4 }, + { "x": 44.1, "y": 19.7 }, + { "x": 39.6, "y": 18.8 }, + { "x": 41.1, "y": 19 }, + { "x": 42.3, "y": 21.2 }, + { "x": 40.1, "y": 18.9 }, + { "x": 42, "y": 19.5 }, + { "x": 41.4, "y": 18.6 }, + { "x": 40.6, "y": 18.8 }, + { "x": 37.6, "y": 19.1 }, + { "x": 41.3, "y": 21.1 }, + { "x": 41.1, "y": 18.2 }, + { "x": 41.6, "y": 18 }, + { "x": 41.1, "y": 19.1 }, + { "x": 41.8, "y": 19.4 }, + { "x": 39.7, "y": 18.4 }, + { "x": 45.8, "y": 18.9 }, + { "x": 42.8, "y": 18.5 }, + { "x": 37.2, "y": 19.4 }, + { "x": 42.1, "y": 19.1 }, + { "x": 42.9, "y": 17.6 }, + { "x": 35.1, "y": 19.4 }, + { "x": 41.3, "y": 20.3 }, + { "x": 36.3, "y": 19.5 }, + { "x": 38.3, "y": 19.2 }, + { "x": 41.1, "y": 18.1 }, + { "x": 39.6, "y": 18.1 }, + { "x": 40.8, "y": 18.9 }, + { "x": 40.3, "y": 18.5 }, + { "x": 43.2, "y": 18.5 }, + { "x": 41, "y": 20 }, + { "x": 37.8, "y": 20 }, + { "x": 39.7, "y": 18.9 }, + { "x": 38.2, "y": 20 }, + { "x": 43.2, "y": 19 }, + { "x": 45.6, "y": 20.3 }, + { "x": 42.2, "y": 19.5 }, + { "x": 42.7, "y": 18.3 }, + { "x": 37.3, "y": 20.5 }, + { "x": 41.1, "y": 18.6 }, + { "x": 37.7, "y": 19.8 }, + { "x": 41.4, "y": 18.5 }, + { "x": 40.6, "y": 19 }, + { "x": 41.5, "y": 18.3 }, + { "x": 44.1, "y": 18 }, + { "x": 43.1, "y": 19.2 }, + { "x": 37.5, "y": 18.5 }, + { "x": 41.1, "y": 17.5 }, + { "x": 40.2, "y": 20.1 }, + { "x": 39.7, "y": 17.9 }, + { "x": 40.6, "y": 17.2 }, + { "x": 40.7, "y": 17 }, + { "x": 39, "y": 18.7 }, + { "x": 39.2, "y": 18.6 }, + { "x": 37.8, "y": 18.1 }, + { "x": 41.5, "y": 18.5 } + ] + }, + { + "id": "panel-03", + "selector": "", + "type": "point", + "title": "Chinstrap - Female", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 46.5, "y": 17.9 }, + { "x": 45.4, "y": 18.7 }, + { "x": 45.2, "y": 17.8 }, + { "x": 46.1, "y": 18.2 }, + { "x": 46, "y": 18.9 }, + { "x": 46.6, "y": 17.8 }, + { "x": 47, "y": 17.3 }, + { "x": 45.9, "y": 17.1 }, + { "x": 58, "y": 17.8 }, + { "x": 46.4, "y": 18.6 }, + { "x": 42.4, "y": 17.3 }, + { "x": 43.2, "y": 16.6 }, + { "x": 46.7, "y": 17.9 }, + { "x": 50.5, "y": 18.4 }, + { "x": 46.4, "y": 17.8 }, + { "x": 40.9, "y": 16.6 }, + { "x": 42.5, "y": 16.7 }, + { "x": 47.5, "y": 16.8 }, + { "x": 47.6, "y": 18.3 }, + { "x": 46.9, "y": 16.6 }, + { "x": 46.2, "y": 17.5 }, + { "x": 45.5, "y": 17 }, + { "x": 50.9, "y": 17.9 }, + { "x": 50.1, "y": 17.9 }, + { "x": 49.8, "y": 17.3 }, + { "x": 48.1, "y": 16.4 }, + { "x": 45.7, "y": 17.3 }, + { "x": 42.5, "y": 17.3 }, + { "x": 45.2, "y": 16.6 }, + { "x": 45.6, "y": 19.4 }, + { "x": 46.8, "y": 16.5 }, + { "x": 45.7, "y": 17 }, + { "x": 43.5, "y": 18.1 }, + { "x": 50.2, "y": 18.7 } + ] + }, + { + "id": "panel-04", + "selector": "", + "type": "point", + "title": "Chinstrap - Male", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 50, "y": 19.5 }, + { "x": 51.3, "y": 19.2 }, + { "x": 52.7, "y": 19.8 }, + { "x": 51.3, "y": 18.2 }, + { "x": 51.3, "y": 19.9 }, + { "x": 51.7, "y": 20.3 }, + { "x": 52, "y": 18.1 }, + { "x": 50.5, "y": 19.6 }, + { "x": 50.3, "y": 20 }, + { "x": 49.2, "y": 18.2 }, + { "x": 48.5, "y": 17.5 }, + { "x": 50.6, "y": 19.4 }, + { "x": 52, "y": 19 }, + { "x": 49.5, "y": 19 }, + { "x": 52.8, "y": 20 }, + { "x": 54.2, "y": 20.8 }, + { "x": 51, "y": 18.8 }, + { "x": 49.7, "y": 18.6 }, + { "x": 52, "y": 20.7 }, + { "x": 53.5, "y": 19.9 }, + { "x": 49, "y": 19.5 }, + { "x": 50.9, "y": 19.1 }, + { "x": 50.8, "y": 18.5 }, + { "x": 49, "y": 19.6 }, + { "x": 51.5, "y": 18.7 }, + { "x": 51.4, "y": 19 }, + { "x": 50.7, "y": 19.7 }, + { "x": 52.2, "y": 18.8 }, + { "x": 49.3, "y": 19.9 }, + { "x": 50.2, "y": 18.8 }, + { "x": 51.9, "y": 19.5 }, + { "x": 55.8, "y": 19.8 }, + { "x": 49.6, "y": 18.2 }, + { "x": 50.8, "y": 19 } + ] + }, + { + "id": "panel-05", + "selector": "", + "type": "point", + "title": "Gentoo - Female", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 46.1, "y": 13.2 }, + { "x": 48.7, "y": 14.1 }, + { "x": 46.5, "y": 13.5 }, + { "x": 45.4, "y": 14.6 }, + { "x": 43.3, "y": 13.4 }, + { "x": 40.9, "y": 13.7 }, + { "x": 45.5, "y": 13.7 }, + { "x": 45.8, "y": 14.6 }, + { "x": 42, "y": 13.5 }, + { "x": 46.2, "y": 14.5 }, + { "x": 45.1, "y": 14.5 }, + { "x": 46.5, "y": 14.5 }, + { "x": 42.9, "y": 13.1 }, + { "x": 48.2, "y": 14.3 }, + { "x": 42.8, "y": 14.2 }, + { "x": 45.1, "y": 14.5 }, + { "x": 49.1, "y": 14.8 }, + { "x": 42.6, "y": 13.7 }, + { "x": 44, "y": 13.6 }, + { "x": 42.7, "y": 13.7 }, + { "x": 45.3, "y": 13.7 }, + { "x": 43.6, "y": 13.9 }, + { "x": 45.5, "y": 13.9 }, + { "x": 44.9, "y": 13.3 }, + { "x": 46.6, "y": 14.2 }, + { "x": 45.1, "y": 14.4 }, + { "x": 46.5, "y": 14.4 }, + { "x": 43.8, "y": 13.9 }, + { "x": 43.2, "y": 14.5 }, + { "x": 45.3, "y": 13.8 }, + { "x": 45.7, "y": 13.9 }, + { "x": 45.8, "y": 14.2 }, + { "x": 43.5, "y": 14.2 }, + { "x": 47.7, "y": 15 }, + { "x": 46.5, "y": 14.8 }, + { "x": 46.4, "y": 15 }, + { "x": 47.5, "y": 14.2 }, + { "x": 45.2, "y": 13.8 }, + { "x": 49.1, "y": 14.5 }, + { "x": 47.4, "y": 14.6 }, + { "x": 44.9, "y": 13.8 }, + { "x": 43.4, "y": 14.4 }, + { "x": 47.5, "y": 14 }, + { "x": 47.5, "y": 15 }, + { "x": 45.5, "y": 14.5 }, + { "x": 44.5, "y": 14.7 }, + { "x": 46.9, "y": 14.6 }, + { "x": 48.4, "y": 14.4 }, + { "x": 48.5, "y": 15 }, + { "x": 47.2, "y": 15.5 }, + { "x": 41.7, "y": 14.7 }, + { "x": 43.3, "y": 14 }, + { "x": 50.5, "y": 15.2 }, + { "x": 43.5, "y": 15.2 }, + { "x": 46.2, "y": 14.1 }, + { "x": 47.2, "y": 13.7 }, + { "x": 46.8, "y": 14.3 }, + { "x": 45.2, "y": 14.8 } + ] + }, + { + "id": "panel-06", + "selector": "", + "type": "point", + "title": "Gentoo - Male", + "axes": { + "x": { + "label": "Bill Length (mm)" + }, + "y": { + "label": "Bill Depth (mm)" + } + }, + "data": [ + { "x": 50, "y": 16.3 }, + { "x": 50, "y": 15.2 }, + { "x": 47.6, "y": 14.5 }, + { "x": 46.7, "y": 15.3 }, + { "x": 46.8, "y": 15.4 }, + { "x": 49, "y": 16.1 }, + { "x": 48.4, "y": 14.6 }, + { "x": 49.3, "y": 15.7 }, + { "x": 49.2, "y": 15.2 }, + { "x": 48.7, "y": 15.1 }, + { "x": 50.2, "y": 14.3 }, + { "x": 46.3, "y": 15.8 }, + { "x": 46.1, "y": 15.1 }, + { "x": 47.8, "y": 15 }, + { "x": 50, "y": 15.3 }, + { "x": 47.3, "y": 15.3 }, + { "x": 59.6, "y": 17 }, + { "x": 48.4, "y": 16.3 }, + { "x": 44.4, "y": 17.3 }, + { "x": 48.7, "y": 15.7 }, + { "x": 49.6, "y": 16 }, + { "x": 49.6, "y": 15 }, + { "x": 50.5, "y": 15.9 }, + { "x": 50.5, "y": 15.9 }, + { "x": 45.2, "y": 15.8 }, + { "x": 48.5, "y": 14.1 }, + { "x": 50.1, "y": 15 }, + { "x": 45, "y": 15.4 }, + { "x": 45.5, "y": 15 }, + { "x": 50.4, "y": 15.3 }, + { "x": 46.2, "y": 14.9 }, + { "x": 54.3, "y": 15.7 }, + { "x": 49.8, "y": 16.8 }, + { "x": 49.5, "y": 16.2 }, + { "x": 50.7, "y": 15 }, + { "x": 46.4, "y": 15.6 }, + { "x": 48.2, "y": 15.6 }, + { "x": 48.6, "y": 16 }, + { "x": 51.1, "y": 16.3 }, + { "x": 45.2, "y": 16.4 }, + { "x": 52.5, "y": 15.6 }, + { "x": 50, "y": 15.9 }, + { "x": 50.8, "y": 17.3 }, + { "x": 51.3, "y": 14.2 }, + { "x": 52.1, "y": 17 }, + { "x": 52.2, "y": 17.1 }, + { "x": 49.5, "y": 16.1 }, + { "x": 50.8, "y": 15.7 }, + { "x": 49.4, "y": 15.8 }, + { "x": 51.1, "y": 16.5 }, + { "x": 55.9, "y": 17 }, + { "x": 49.1, "y": 15 }, + { "x": 46.8, "y": 16.1 }, + { "x": 53.4, "y": 15.8 }, + { "x": 48.1, "y": 15.1 }, + { "x": 49.8, "y": 15.9 }, + { "x": 51.5, "y": 16.3 }, + { "x": 55.1, "y": 16 }, + { "x": 48.8, "y": 16.2 }, + { "x": 50.4, "y": 15.7 }, + { "x": 49.9, "y": 16.1 } + ] + } + ] +}