Skip to content

feat(workflow-operator): volcano plot labels follow columns - #9040

Open
eugenegujing wants to merge 4 commits into
apache:mainfrom
eugenegujing:fix/volcano-plot-axis-labels
Open

eugenegujing wants to merge 4 commits into
apache:mainfrom
eugenegujing:fix/volcano-plot-axis-labels

Conversation

@eugenegujing

@eugenegujing eugenegujing commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Root cause: VolcanoPlotOpDesc.generatePythonCode hard-codes the y column as the literal "-log10(pvalue)" and plots it under that name, so the y axis always says -log10(pvalue) even when the selected column is padj. The title is the literal "Volcano Plot" and the x axis and color bar show the raw effect column name. None of this can be changed from the property panel.

Before:  P-Value Column = padj  ->  y column "-log10(pvalue)"  ->  y axis "-log10(pvalue)"
After:   P-Value Column = padj  ->  y column "-log10(padj)"    ->  y axis "-log10(padj)", or the Y Label the user typed

The y column is now named after the selected p-value column, so the axis and the hover text say which column was transformed. Three optional label properties are added, empty by default:

Property Empty Set
Title Volcano Plot the text typed
X Label effect column name the text typed
Y Label -log10(<p-value column>) the text typed

The color bar has no label of its own: the points are colored by the effect column, the same column that is on the x axis, so the color bar carries the X Label text (or the effect column name when X Label is empty). If a later change lets the color encode a different column, a label for it would come with that change.

The labels go through fig.update_layout(xaxis_title, yaxis_title, coloraxis_colorbar_title_text), same as Line Chart's X Label / Y Label. Each label is an EncodableString, so quotes and non-ASCII text are fine. A whitespace-only field counts as empty. The hover box still shows raw column names (plotly behaviour, same as Line Chart).

Behavior change for saved workflows: a workflow with padj as the p-value column now renders -log10(padj) instead of -log10(pvalue). That is the fix.

Since #8504 merged, the operator also has an export path, generateStandaloneCode(), which writes the same figure as a standalone script. It carried the same hard-coded "-log10(pvalue)" and title="Volcano Plot", so this PR applies the same change there: the y column is named after the selected p-value column and the three labels go through fig.update_layout as escaped Python literals (the export has no decoder, so pyStringLiteral escapes quotes and backslashes). The engine template and the exported script now label the figure the same way, and a spec checks that across the label combinations.

Rebase note: coloraxis_colorbar_title_text is emitted unconditionally, in both templates. Once the significance-coloring PR (#9039) lands, the categorical mode has no coloraxis, so whichever branch rebases second needs to make that entry conditional.

Figures below are the operator's generated Python from main and from this branch, run on the 430-gene example workflow from the issue; the third one has the title and both axis labels filled in.

Before After (defaults) After (labels set)
before-main labels-after-default labels-after-custom

Any related issues, documentation, discussions?

Closes #9037

PR #8504 (merged) added the generateStandaloneCode() export path with the same hard-coded "-log10(pvalue)"; the mirroring described above is the follow-up it needed.

How was this PR tested?

New tests in VolcanoPlotOpDescSpec, written before the source change:

  • y column and axis are named after the selected p-value column; the old literal is gone
  • every label falls back to its default when empty or whitespace-only
  • a set label replaces its default and reaches the code only as a decode site (sentinels with quotes, backslash, non-ASCII)
  • the color bar title follows X Label when it is set and the effect column name otherwise
  • one set label leaves the other two at their defaults
  • a workflow JSON saved before this change (only the two column keys) generates byte-for-byte the same code as a default-constructed operator
  • generateStandaloneCode: the y column and axis are named after the p-value column (including a name with a quote, p"adj), the labels fall back to the column-derived defaults, a set label is emitted as an escaped literal and the default title is gone, the color bar carries the X Label text, whitespace-only keeps the default, a saved workflow renders as a default-constructed operator, and a cross-path test with the title and X Label set checks that the engine template and the exported script carry the same title, axis and color bar labels
sbt -Dsbt.server.forcestart=true "WorkflowOperator/testOnly *VolcanoPlotOpDescSpec"
# Tests: succeeded 18, failed 0, canceled 0, ignored 0, pending 1   (the pending one is pre-existing)

sbt -Dsbt.server.forcestart=true "WorkflowOperator/scalafmtAll" "WorkflowOperator/Test/scalafmtAll"
sbt -Dsbt.server.forcestart=true "WorkflowOperator/scalafixAll --check"
# success

Smoke run: the generated code was executed outside Texera (pytexera stubbed, pandas + plotly 5.24.1) on the 430-gene mock table. Defaults give title Volcano Plot, x lfc_shrunk, y -log10(padj), color bar lfc_shrunk; with the labels set the figure shows the typed text; whitespace-only title and y label fall back to the defaults. The exported script for the default and the all-labels configuration parses with ast.parse.

Was this PR authored or co-authored using generative AI tooling?

Yes. Generated-by: Claude Code (claude-fable-5-1). Co-authored with Claude; the author reviewed the change before submission.

Name the y column and its axis -log10(<p-value column>) instead of the fixed "-log10(pvalue)". Add optional Title, X Label, Y Label and Color Bar Label properties that override the column-derived text when set; an empty or blank field keeps the default.
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @kz930, @Yicong-Huang
    You can notify them by mentioning @kz930, @Yicong-Huang in a comment.

@codecov-commenter

codecov-commenter commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.95%. Comparing base (98c6337) to head (969e324).
⚠️ Report is 24 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #9040      +/-   ##
============================================
+ Coverage     91.87%   91.95%   +0.07%     
- Complexity     5049     5092      +43     
============================================
  Files          1265     1276      +11     
  Lines         54915    55506     +591     
  Branches       6940     7039      +99     
============================================
+ Hits          50453    51039     +586     
+ Misses         2769     2725      -44     
- Partials       1693     1742      +49     
Flag Coverage Δ *Carryforward flag
access-control-service 77.44% <ø> (+0.06%) ⬆️
agent-service 99.16% <ø> (ø) Carriedforward from ba9e78d
amber 86.41% <100.00%> (+0.34%) ⬆️
computing-unit-managing-service 61.81% <ø> (+1.33%) ⬆️
config-service 87.50% <ø> (+0.12%) ⬆️
file-service 82.29% <ø> (+0.28%) ⬆️
frontend 96.50% <ø> (ø) Carriedforward from ba9e78d
notebook-migration-service 83.77% <ø> (+0.03%) ⬆️
pyamber 98.54% <ø> (ø) Carriedforward from ba9e78d
workflow-compiling-service 74.25% <ø> (+1.81%) ⬆️

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 10 worse · ⚪ 5 noise (<±5%) · 0 without baseline

Compared against main bc4f3c8 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 372 0.227 26,298/34,115/34,115 us 🔴 +19.4% / 🔴 +179.1%
🔴 bs=100 sw=10 sl=64 804 0.491 122,492/158,874/158,874 us 🔴 +7.9% / 🔴 +82.3%
🔴 bs=1000 sw=10 sl=64 960 0.586 1,033,465/1,178,878/1,178,878 us 🔴 +7.9% / 🔴 +44.1%
Baseline details

Latest main bc4f3c8 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 372 tuples/sec 433 tuples/sec 1,019 tuples/sec -14.1% -63.5%
bs=10 sw=10 sl=64 MB/s 0.227 MB/s 0.264 MB/s 0.622 MB/s -14.0% -63.5%
bs=10 sw=10 sl=64 p50 26,298 us 23,317 us 10,144 us +12.8% +159.2%
bs=10 sw=10 sl=64 p95 34,115 us 28,582 us 12,225 us +19.4% +179.1%
bs=10 sw=10 sl=64 p99 34,115 us 28,582 us 15,527 us +19.4% +119.7%
bs=100 sw=10 sl=64 throughput 804 tuples/sec 872 tuples/sec 1,371 tuples/sec -7.8% -41.4%
bs=100 sw=10 sl=64 MB/s 0.491 MB/s 0.532 MB/s 0.837 MB/s -7.7% -41.3%
bs=100 sw=10 sl=64 p50 122,492 us 113,537 us 79,910 us +7.9% +53.3%
bs=100 sw=10 sl=64 p95 158,874 us 156,040 us 87,155 us +1.8% +82.3%
bs=100 sw=10 sl=64 p99 158,874 us 156,040 us 106,643 us +1.8% +49.0%
bs=1000 sw=10 sl=64 throughput 960 tuples/sec 963 tuples/sec 1,415 tuples/sec -0.3% -32.2%
bs=1000 sw=10 sl=64 MB/s 0.586 MB/s 0.588 MB/s 0.864 MB/s -0.3% -32.2%
bs=1000 sw=10 sl=64 p50 1,033,465 us 1,030,425 us 780,407 us +0.3% +32.4%
bs=1000 sw=10 sl=64 p95 1,178,878 us 1,092,916 us 817,814 us +7.9% +44.1%
bs=1000 sw=10 sl=64 p99 1,178,878 us 1,092,916 us 848,683 us +7.9% +38.9%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,537.47,200,128000,372,0.227,26298.41,34115.30,34115.30
1,100,10,64,20,2488.67,2000,1280000,804,0.491,122491.57,158873.58,158873.58
2,1000,10,64,20,20842.47,20000,12800000,960,0.586,1033465.45,1178877.82,1178877.82

@kz930 kz930 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.

The color bar always shows the effect column, which is the same column as the x axis, so is a separate Color Bar Label needed, or could it follow X Label?

…label

Drop the Color Bar Label property; the points are colored by the effect column that is on the x axis, so the color bar now carries the X Label text in both the engine template and the exported script.
@eugenegujing

Copy link
Copy Markdown
Contributor Author

@kz930 You're correct. The color bar now takes the X Label text and the separate Color Bar Label property is removed in 969e324

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Volcano Plot labels the y axis "-log10(pvalue)" regardless of the selected column, and offers no title / axis / color-bar labels

3 participants