Skip to content

Commit 76cd4e1

Browse files
kesemoonclaude
andcommitted
Rebuild R web bundle with latest app; add ecology example script
- Replaces stale pre-built assets in figaro-r/inst/www/ with current build (npm run build:r) so R users get the up-to-date UI without needing Node.js - Adds figaro_example_script.R: 3-panel ecology demo (elevation gradient, species abundance distribution, community composition) - README: documents the contributor rebuild-and-commit workflow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent bb3ecba commit 76cd4e1

7 files changed

Lines changed: 588 additions & 346 deletions

File tree

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ figaro(my_data = my_df)
5959

6060
See [R_INTEGRATION.md](R_INTEGRATION.md) for the complete guide including ggplot2 support, base-R plots, and image inputs.
6161

62+
### Keeping the R bundle up to date (contributors only)
63+
64+
The web app served by the R package is a pre-built snapshot stored in
65+
`figaro-r/inst/www/`. R users do **not** need Node.js — they just clone and run
66+
`source("install.R")`.
67+
68+
When you pull changes to the web app source and want to ship them to R users,
69+
rebuild the bundle and commit it:
70+
71+
```bash
72+
npm install
73+
npm run build:r
74+
cp -r dist-r/. figaro-r/inst/www/ # macOS / Linux
75+
# or on Windows PowerShell:
76+
# Copy-Item -Recurse -Force dist-r\* figaro-r\inst\www\
77+
git add figaro-r/inst/www/
78+
git commit -m "Rebuild R web bundle"
79+
git push
80+
```
81+
82+
Building on Windows and pushing for Mac/Linux users is safe — git normalises
83+
line endings on commit (`core.autocrlf = true`).
84+
6285
---
6386

6487
## Technical overview

figaro-r/inst/www/assets/index-DWix516s.js renamed to figaro-r/inst/www/assets/index-CaC0X6Q1.js

Lines changed: 334 additions & 324 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

figaro-r/inst/www/assets/index-DFCG9QJB.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

figaro-r/inst/www/assets/index-xez5Bhk9.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

figaro-r/inst/www/assets/index.es-Cm41F_5y.js renamed to figaro-r/inst/www/assets/index.es-CRoVUjBM.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

figaro-r/inst/www/index.html

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
<!doctype html>
2-
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8" />
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<link rel="preconnect" href="https://fonts.googleapis.com" />
7-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8-
<link
9-
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Roboto:wght@400;500;700&family=Source+Sans+3:wght@400;600;700&family=Lato:wght@400;700&family=Merriweather:wght@400;700&family=IBM+Plex+Mono:wght@400;500&display=swap"
10-
rel="stylesheet"
11-
/>
12-
<link rel="icon" type="image/png" href="./figaro_logo_v2.png" />
13-
<title>Figaro</title>
14-
<script type="module" crossorigin src="./assets/index-DWix516s.js"></script>
15-
<link rel="stylesheet" crossorigin href="./assets/index-xez5Bhk9.css">
16-
</head>
17-
<body>
18-
<div id="root"></div>
19-
</body>
20-
</html>
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<link rel="preconnect" href="https://fonts.googleapis.com" />
7+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8+
<link
9+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Roboto:wght@400;500;700&family=Source+Sans+3:wght@400;600;700&family=Lato:wght@400;700&family=Merriweather:wght@400;700&family=IBM+Plex+Mono:wght@400;500&display=swap"
10+
rel="stylesheet"
11+
/>
12+
<link rel="icon" type="image/png" href="./figaro_logo_v2.png" />
13+
<title>Figaro</title>
14+
<script type="module" crossorigin src="./assets/index-CaC0X6Q1.js"></script>
15+
<link rel="stylesheet" crossorigin href="./assets/index-DFCG9QJB.css">
16+
</head>
17+
<body>
18+
<div id="root"></div>
19+
</body>
20+
</html>

figaro_example_script.R

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# =============================================================================
2+
# Figaro — Ecology Example Script
3+
# =============================================================================
4+
#
5+
# This script walks ecologists through installing Figaro and composing a
6+
# publication-ready 3-panel figure from simulated survey data:
7+
#
8+
# Panel A Species richness along an elevation gradient (scatter + LOESS)
9+
# Panel B Species abundance distribution (histogram)
10+
# Panel C Bird community composition by habitat (stacked bar)
11+
#
12+
# All data are simulated so the script runs without any external files.
13+
# =============================================================================
14+
15+
16+
# ── 0. INSTALLATION ─────────────────────────────────────────────────────────
17+
#
18+
# Run this section once, then skip it on future runs.
19+
#
20+
# Step 1 — clone the repository (run in a terminal, not in R):
21+
#
22+
# git clone https://github.com/yuvalbloch/figaro-.git
23+
#
24+
# Step 2 — set your R working directory to the cloned folder:
25+
#
26+
# setwd("C:/path/to/figaro-") # Windows — adjust to where you cloned it
27+
# setwd("~/path/to/figaro-") # macOS / Linux
28+
#
29+
# Step 3 — install required packages and the figaro R package:
30+
31+
# install.packages(c("jsonlite", "httpuv", "ggplot2")) # CRAN dependencies
32+
source("install.R") # installs figaro itself
33+
34+
# After installation you should see:
35+
# Done! Load the package in any R session with:
36+
# library(figaro)
37+
# =============================================================================
38+
39+
40+
# ── 1. Load packages ────────────────────────────────────────────────────────
41+
42+
library(figaro)
43+
library(ggplot2)
44+
45+
46+
# ── 2. Simulate ecological survey data ──────────────────────────────────────
47+
48+
set.seed(42)
49+
50+
# 2a. Elevation-gradient survey
51+
# 150 vegetation plots sampled across an altitudinal gradient (200–3 000 m).
52+
# Species richness follows a mid-domain / hump-shaped response peaking near
53+
# 1 400 m, a classic pattern in mountain biogeography.
54+
55+
n_plots <- 150
56+
elevation <- runif(n_plots, 200, 3000)
57+
58+
richness <- pmax(
59+
round(40 * exp(-((elevation - 1400) / 700)^2) + rnorm(n_plots, 0, 3)),
60+
1L
61+
)
62+
63+
veg_zone <- cut(
64+
elevation,
65+
breaks = c(0, 800, 1600, 2400, 3100),
66+
labels = c("Lowland forest", "Montane forest", "Subalpine", "Alpine")
67+
)
68+
69+
gradient_df <- data.frame(
70+
elevation_m = elevation,
71+
species_richness = richness,
72+
vegetation_zone = veg_zone
73+
)
74+
75+
76+
# 2b. Species abundance distribution (SAD)
77+
# 200-species community following a log-normal SAD — the canonical "hollow
78+
# curve" seen in real communities (Preston 1948; McGill et al. 2007).
79+
80+
n_sp <- 200
81+
sad_df <- data.frame(
82+
log10_abundance = rnorm(n_sp, mean = 3.5, sd = 1.2)
83+
)
84+
85+
86+
# 2c. Bird community composition across five habitat types
87+
# Counts of individuals assigned to five foraging guilds, reflecting
88+
# well-known habitat-filtering patterns (e.g. frugivores dominate forest,
89+
# insectivores peak in wetlands and riparian zones).
90+
91+
habitats <- c("Riparian", "Grassland", "Shrubland", "Forest", "Wetland")
92+
guilds <- c("Insectivores", "Granivores", "Frugivores",
93+
"Nectarivores", "Omnivores")
94+
95+
counts <- c(
96+
30, 18, 12, 25, 15, # Riparian
97+
45, 8, 5, 10, 12, # Grassland
98+
20, 15, 8, 18, 19, # Shrubland
99+
12, 10, 22, 30, 26, # Forest
100+
38, 12, 6, 20, 24 # Wetland
101+
)
102+
103+
composition_df <- data.frame(
104+
habitat = factor(rep(habitats, each = length(guilds)), levels = habitats),
105+
guild = factor(rep(guilds, times = length(habitats)), levels = guilds),
106+
count = counts
107+
)
108+
109+
110+
# ── 3. Build ggplot2 panels ─────────────────────────────────────────────────
111+
112+
# Colour palettes — colourblind-friendly
113+
zone_pal <- c("Lowland forest" = "#4caf50",
114+
"Montane forest" = "#1b5e20",
115+
"Subalpine" = "#8d6e63",
116+
"Alpine" = "#90a4ae")
117+
118+
guild_pal <- c("Insectivores" = "#e53935",
119+
"Granivores" = "#fb8c00",
120+
"Frugivores" = "#43a047",
121+
"Nectarivores" = "#8e24aa",
122+
"Omnivores" = "#1e88e5")
123+
124+
125+
# Panel A — Species richness × elevation
126+
# Two layers (geom_point + geom_smooth) → Figaro renders as an image panel
127+
# with the R Plot Style editor for live re-styling.
128+
129+
panel_a <- ggplot(gradient_df,
130+
aes(elevation_m, species_richness, colour = vegetation_zone)) +
131+
geom_point(alpha = 0.65, size = 2.2) +
132+
geom_smooth(method = "loess", se = TRUE, span = 0.5,
133+
colour = "black", linewidth = 0.9, linetype = "dashed") +
134+
scale_colour_manual(values = zone_pal, name = "Vegetation zone") +
135+
labs(title = "A Species richness along an elevation gradient",
136+
x = "Elevation (m a.s.l.)",
137+
y = "Vascular plant species richness") +
138+
theme_classic(base_size = 12) +
139+
theme(legend.position = "right")
140+
141+
142+
# Panel B — Species abundance distribution
143+
# Single geom_histogram layer → Figaro extracts as a native histogram panel
144+
# (column mappings and axis labels are editable in the Inspector).
145+
146+
panel_b <- ggplot(sad_df, aes(log10_abundance)) +
147+
geom_histogram(bins = 22, fill = "#1565c0", colour = "white", alpha = 0.85) +
148+
labs(title = "B Species abundance distribution",
149+
x = "log₁₀(abundance)",
150+
y = "Number of species") +
151+
theme_classic(base_size = 12)
152+
153+
154+
# Panel C — Community composition (proportional stacked bar)
155+
# Single geom_col layer → Figaro extracts as a native bar/stacked-bar panel.
156+
157+
panel_c <- ggplot(composition_df, aes(habitat, count, fill = guild)) +
158+
geom_col(position = "fill") +
159+
scale_fill_manual(values = guild_pal, name = "Foraging guild") +
160+
scale_y_continuous(labels = \(x) paste0(round(x * 100), "%")) +
161+
labs(title = "C Bird community composition by habitat",
162+
x = "Habitat type",
163+
y = "Relative abundance") +
164+
theme_classic(base_size = 12) +
165+
theme(axis.text.x = element_text(angle = 35, hjust = 1))
166+
167+
168+
# ── 4. Open Figaro ──────────────────────────────────────────────────────────
169+
#
170+
# Layout: Panel A spans the full top row; B and C share the bottom row.
171+
#
172+
# ┌─────────────────────────┐
173+
# │ A │ ← elevation gradient (wider)
174+
# ├────────────┬────────────┤
175+
# │ B │ C │ ← SAD histogram | composition bar
176+
# └────────────┴────────────┘
177+
178+
layout_m <- matrix(c(1, 1,
179+
2, 3), nrow = 2, byrow = TRUE)
180+
181+
fig <- figaro(
182+
elevation_gradient = panel_a,
183+
abundance_dist = panel_b,
184+
community_comp = panel_c,
185+
layout = layout_m,
186+
row_sizes = c(1.3, 1), # give the scatter a bit more vertical space
187+
canvas = "A4_landscape"
188+
)
189+
190+
# Your browser will open with the three panels pre-loaded.
191+
#
192+
# Things to try in the browser
193+
# ─────────────────────────────
194+
# • Click any panel → the Inspector on the right lets you change titles,
195+
# axis labels, colours, and chart type.
196+
# • Panels B and C are native Figaro charts: map different columns, switch
197+
# chart types, or link their x-axes from the Inspector.
198+
# • Panel A opened with the R Plot Style editor (bottom of the Inspector):
199+
# change the base font size or legend position and click "Apply style" to
200+
# re-render the ggplot2 object live.
201+
# • Drag the dividers between panels to adjust proportions.
202+
# • Export → SVG / PNG (1× 2× 3×) / PDF / HTML via the ↓ icon in the toolbar.
203+
# • Save → writes a .figaro.json session file you can reopen later with:
204+
# figaro(session = "my_figure.figaro.json")
205+
206+
207+
# ── 5. Stop the server when you are done ────────────────────────────────────
208+
209+
# figaro_stop()

0 commit comments

Comments
 (0)