What 45,000 plant-science questions taught us about platform UI
A pull request landed on our mobile app last week. A small UX cleanup: a banner that used to list every “pinned” answer during a measurement loop, trimmed down to one. Cleaner, simpler, less visual clutter. Good change.
Except how it picked the one:
const firstAutoProceededWithPlot = flowNodes.find(
(n) =>
n.type === "question" &&
isAutoincrementEnabled(n.id) &&
!!getAnswer(iterationCount, n.id)?.trim() &&
/(plot)/i.test(`${n.name ?? ""} ${n.content?.text ?? ""}`),
);
The banner only renders if one of your pinned questions contains the literal string “plot” in its label or text. If it does, you get a header that reads “Your current plot.” If it doesn’t, the banner silently disappears.
I get the instinct. You look at the test experiments on your desk and half the questions are “Plot number”, “Plot ID”, “plot”; the UX team wants to declutter the banner; you ship the regex and move on.
The problem is that openJII isn’t a JII-only app. It’s a platform. And platforms don’t get to decide what their users call things.
The data, briefly
Reviewing the PR, my first reaction was a hunch: “what if they call it plant, or leaf, or translate it into anything else?” Hunches are cheap. They’re also not particularly persuasive on their own.
The next step would normally be expensive: go get numbers. Except the numbers were already sitting in a notebook nearby. A few weeks earlier I’d run a semantic analysis on 45,451 free-text questions across 19,658 PhotosynQ projects. PhotosynQ is the commercial plant-science measurement platform some of JII’s members helped build over the last decade. openJII is the open-source platform we run today, with feature parity and more, and JII retained ownership of the data, which is why this analysis was open to us in the first place.
The analysis answered a different research question (what metadata concepts do plant-science teams actually use?), but the answer also addressed the PR.
After three layers of cleanup (rule-based concept tagging across 22 concepts and 182 multilingual terms, fuzzy clustering on the top 500 normalised forms, and character-n-gram TF-IDF clustering on the long tail), here’s the cross-experiment ranking. Number of distinct projects that use each identifier concept:
| concept | projects | label variants |
|---|---|---|
| treatment | 5,592 | 539 |
| rep | 4,074 | 492 |
| plant | 3,783 | 1,213 |
| leaf | 3,265 | 1,274 |
| genotype | 2,104 | 361 |
| plot | 1,729 | 291 |
| color | 1,258 | 269 |
| species | 938 | 251 |
| variety | 801 | 161 |
| sample | 795 | 251 |
Plot is sixth.
Not universal. Not even dominant. It sits behind treatment, rep, plant, leaf, and genotype, all ordinary enough that any “cleaner UX” argument that applies to plot applies equally to each of them.
And that’s just the English variants. The 1,729 projects that do use a plot concept use 291 distinct spellings: Plot, N PLOT, Plot no, Plot#, plot number, nplot. Spanish parcela and parcelas. French parcelle. German Parzelle. Portuguese parcela. Chinese xiao qu (小区). Russian Cyrillic. The hardcoded /plot/i match catches some of the English variants and literally none of the others.
Even when the keyword rules are widened to cover Spanish, French, German, Portuguese, and Chinese (as the full analysis does), only 62.8% of labels match any keyword concept at all. The remaining 37% are conversational (“Which treatment was applied?”, “¿Cuál es la variedad?”, “测量条件是什么?”), domain-specific (DAS, DAP, Cultivar, NDVI), or experiment-local. No regex on “plot” reaches them.
The platform lesson
The data makes a point more firmly than any gut check could: if you hardcode “plot” into your platform UI (whether it’s a regex, a conditional, or a string), you are deciding on behalf of every tenant that their experiments revolve around plots. A decade of PhotosynQ’s history shows the majority don’t. They revolve around treatments, replicates, plants, leaves, genotypes, whatever the scientist is actually measuring.
A platform doesn’t get to make that call.
The right fix isn’t to stretch the regex. It’s to move the semantics out of free text:
- Typed question identifiers. Give the platform a concept of “this question is the plot identifier” (or the treatment identifier, or the replicate counter) as a property of the question itself, not a substring of its label. A researcher designing an experiment opts in explicitly.
- A “show in summary” flag on the question. The same mechanism works for anyone’s workflow: treatment, rep, genotype, or something the platform authors never anticipated. You tell the platform which question matters; the platform doesn’t guess.
- Internationalised banner copy. “Your current plot” becomes “Your current {label}”, sourced from the question’s actual name, in the researcher’s language.
These are easy decisions to skip in the name of shipping a small UX fix. They’re exactly the decisions that compound when you’re building a platform meant to serve teams beyond your own four walls.
Why I like this story
The PR review comment rewrote itself. Instead of “I think this is fragile”, I could paste a concrete ranking table and a chart. The discussion moved from “convince me” to “okay, what do we actually want to build?” in one round.
That’s the part I keep coming back to. Most of what a platform team decides never gets a clean public case study. Decisions get made in Slack, in a whiteboard session, under a deadline. The ones informed by real data are the exceptions.
When you’re building an open platform for science, the pressure to hardcode domain vocabulary into your UI is constant. And the cost shows up, quietly, in every experiment your platform fails to serve.