Skip to content

Critical and triple points, saturation scale, labels inside the dome; versions in the badge - #43

Merged
jowr merged 7 commits into
masterfrom
chp/dazzling-ride-7bvl7p
Nov 3, 2026
Merged

jowr merged 7 commits into
masterfrom
chp/dazzling-ride-7bvl7p

Conversation

@jowr

@jowr jowr commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Addresses #39: three optional additions to property diagrams, and one changed default.

Summary

Critical and triple points (diagram.marked_points = ("critical", "triple"))

  • A dot in the colour and casing of the saturation curve; it follows set_line_style("saturation", ...).
  • "triple" marks both ends of the saturation curve at the triple temperature (saturated liquid and vapour).
  • A point is drawn only inside the chart's T-p box. The default region "DEF" starts 1 % above the triple point, so the triple point needs tp_limits=[None, None, None, None]. When a point is drawn, the axes widen by 1.5 % of the span so the dot is not cut off at the frame.
  • Mixtures and pseudo-pure blends (R407C) mark the critical point only.
  • The dots draw at z 3.5: above the dome and the single lines of Highlighting single isolines #32 (z 3.0), below the labels.

Saturation scale (diagram.saturation_scale = True, or {"step": 10, "Q": 0})

  • A scale just inside the frame, right of the vertical axis: saturation temperatures next to a pressure axis (p-h, p-s, p-rho), saturation pressures next to a temperature axis (T-s, T-rho). The h-s and p-T charts have none; asking for one raises an error that says why.
  • Ticks sit on round values in the chart's units, up to the critical point: a given step, or chosen by the chart (1-2-5 per decade for pressures).
  • Q picks the dew point (the default) or the bubble point of a blend.
  • Values that would overlap are left out, from the top down.
  • It uses the colour, width and length of the axis ticks. Isoline labels, the legend and the badge keep clear of it, and it never changes the axes.

Labels inside the dome (settings.with_(labels={"dome": True}))

  • Two more labels on each labelled isotherm (isobar on a T-s chart): one just right of the bubble line, one just left of the dew line. They come on top of the labels of the label mode, which do not change.
  • They sit on the chord between the bubble and dew states and turn with it, so on a blend they follow the slope the glide gives the isotherms.
  • They keep clear of the other labels, the legend, the badge, the scale and cycles. A label that does not fit is left out; near the critical point that leaves one label of a line, then none.

Changed default: versions in the badge

  • BrandingSettings.versions is now True, so the badge of a new chart also says "CoolProp x, CoolPlot y".
  • Specs saved since 1.2 hold "versions": false and keep their badge as it was.
  • A chart without badge now takes {"references": "none", "versions": False}; "references": "none" alone leaves the versions line. The upgrade guide has a 1.5 to 1.6 section on this.

How it is built

  • The engine computes the states that need CoolProp (the marked points, the scale ticks, the bubble and dew ends) together with the domain, and caches them per fluid.
  • The composer only places items. It uses existing scene item types (Markers, Line, Text), so no renderer needed a change.
  • coolplot-core 1.6 composes the same scenes from the new optional "points", "scale" and "dome" keys of the compose record. The bridge refuses these features for an older core, so the Python composer draws them, with a warning.
  • The new spec fields (marked_points, saturation_scale, labels.dome) are written to the record only when set, so records of 1.5 read and draw as before.
  • Master is merged in (single lines Highlighting single isolines #32, phase diagram examples Add phase diagram examples for CO2 and water #42, CI CI: test branches through their pull request, not on every push too #44). Both sides add to DiagramSpec, the composer and coolplot-core 1.6.

Tests

  • New modules: tests/test_marked_points.py, tests/test_saturation_scale.py, tests/test_dome_labels.py. tests/test_native_core.py compares the Python composer with the C++ port for each feature and checks that an older core is refused.
  • C++: 9 new golden cases generated by make_data.py (compose_rails_*marked_points*, *scale*, *dome_labels*). After the merge of Highlighting single isolines #32, 53 C++ test cases pass, and the JS SVG writer check reports all files identical.
  • Full suite on the merge of Highlighting single isolines #32: 615 passed with the Python composer, 675 passed through coolplot-core with CoreFallbackWarning as an error. CI was green there, including core and docs.
  • Parity sweep (not committed): 429 charts, with all three features on, single lines, cycles, four label modes, three plot sizes and three theme/unit combinations, composed by Python and by coolplot-core, also with previous labels. 426 match exactly. The other 3 fail the same way on master without these features: an inline-mode label with a zero direction on a blend T-rho chart. That is left to a separate fix.
  • After the merge of Add phase diagram examples for CO2 and water #42 and CI: test branches through their pull request, not on every push too #44 (only CHANGELOG.md conflicted): the phase diagram examples pass both ways, the feature, branding and port tests pass through coolplot-core (120), and mypy is clean. CI is running on that head.

Docs: how_to/isolines.md (marked points, saturation scale), how_to/labels.md (labels inside the dome), how_to/branding.md, upgrade.md, reference/contracts.md, CHANGELOG.md.


Generated by Claude Code

jowr and others added 5 commits November 3, 2026 09:56
DiagramSpec.marked_points and PropertyDiagram.marked_points take
"critical" and or "triple". The engine computes the states once per
fluid (thermo.provider.marked_point_states) and hands them to the
composer with the domain. The triple point marks both ends of the
saturation curve at the triple temperature; mixtures and pseudo-pure
blends have none. Points outside the T-p box are not drawn, and the
axes are widened a little so the dots are drawn whole. The dot takes
the colour and casing of the saturation curve.

coolplot-core 1.6 composes the same scene from the "points" of the
compose record; the bridge refuses marked points for an older core.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
DiagramSpec.saturation_scale (a SaturationScale) and
PropertyDiagram.saturation_scale draw a scale just inside the frame,
right of the vertical axis: saturation temperatures next to a pressure
axis, saturation pressures next to a temperature axis. Ticks land on
round values in the chart's units, either a given step or chosen by
the chart (1-2-5 per decade for pressures), up to the critical point.
"Q" picks the dew (default) or bubble point of a blend. Values that
would overlap are thinned from the top down. The scale takes the
colour and length of the axis ticks; isoline labels, the legend and
the badge keep clear of it, and it never widens the axes.

The engine computes the ticks with the domain; coolplot-core 1.6
composes the same scene from the "scale" of the compose record, and
the bridge refuses a scale for an older core.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
LabelSettings.dome adds two labels to each labelled line of the family
that crosses the two-phase region: the isotherms, or the isobars where
temperature is an axis (spec.diagram.dome_key). They sit on the chord
between the bubble and dew states, a few points inside each end and
turned along it, so they follow the sloped isotherms of a blend. They
come on top of the labels of the label mode and keep clear of those,
the legend, the badge, the saturation scale and cycles; a label that
does not fit is left out, which near the critical point leaves one
label of a line, then none.

The engine computes the bubble and dew states of the planned values
with the domain; coolplot-core 1.6 places the same labels from the
"dome" of the compose record, and the bridge refuses the setting for an
older core.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
BrandingSettings.versions is True by default, so the badge of a new
chart holds the versions line ("CoolProp 8.0.0, CoolPlot 1.6.0") below
the equation of state. Specs saved since 1.2 hold "versions": false and
keep their badge; a spec from before 1.2 still reads without badge. A
chart without badge now takes references "none" and versions False;
the docs, the upgrade guide and the tests say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3f595ad4-662b-4d6a-adfb-35d0aa2f725f
Commits

Reviewing files that changed from the base of the PR and between ba86c95 and 24b7588.

Files ignored due to path filters: 7
  • cpp/tests/data/compose_rails_blend_ph_bubble_scale.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_blend_ph_dome_labels_edge.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_r290_ph_dome_labels.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_r290_ph_saturation_scale.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_water_ts_dome_labels.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_water_ts_marked_points.svg is excluded by !**/*.svg
  • cpp/tests/data/compose_rails_water_ts_saturation_scale.svg is excluded by !**/*.svg
Files selected for processing: 37
  • CHANGELOG.md
  • cpp/include/coolplot/compose.h
  • cpp/include/coolplot/layout.h
  • cpp/include/coolplot/spec.h
  • cpp/src/compose.cpp
  • cpp/src/layout.cpp
  • cpp/src/spec.cpp
  • cpp/tests/data/compose_rails_blend_ph_bubble_scale.json
  • cpp/tests/data/compose_rails_blend_ph_dome_labels_edge.json
  • cpp/tests/data/compose_rails_r290_ph_dome_labels.json
  • cpp/tests/data/compose_rails_r290_ph_saturation_scale.json
  • cpp/tests/data/compose_rails_water_ts_dome_labels.json
  • cpp/tests/data/compose_rails_water_ts_marked_points.json
  • cpp/tests/data/compose_rails_water_ts_saturation_scale.json
  • cpp/tests/data/make_data.py
  • cpp/tests/test_compose.cpp
  • docs/how_to/branding.md
  • docs/how_to/isolines.md
  • docs/how_to/labels.md
  • docs/reference/contracts.md
  • docs/upgrade.md
  • src/coolplot/compose/builder.py
  • src/coolplot/compose/layout.py
  • src/coolplot/corelib.py
  • src/coolplot/diagram.py
  • src/coolplot/engine/engine.py
  • src/coolplot/engine/planning.py
  • src/coolplot/spec/__init__.py
  • src/coolplot/spec/diagram.py
  • src/coolplot/spec/settings.py
  • src/coolplot/thermo/provider.py
  • tests/test_api_vocabulary.py
  • tests/test_branding.py
  • tests/test_dome_labels.py
  • tests/test_marked_points.py
  • tests/test_native_core.py
  • tests/test_saturation_scale.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

jowr and others added 2 commits November 3, 2026 11:50
Both sides add to DiagramSpec, the composer and coolplot-core 1.6. The
single lines draw at z 3.0; the marked critical and triple points move
to z 3.5, above them and below the labels (one golden case written
again). The single lines go after the labels inside the dome.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
CHANGELOG: the examples join the Added list; the units entry was already
under Changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013bsHH774XBx3sJCtfvvuGF
@jowr
jowr merged commit 7c8f93a into master Nov 3, 2026
10 checks passed
@jowr
jowr deleted the chp/dazzling-ride-7bvl7p branch November 3, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant