Skip to content

Pin tick locations before setting rotated tick labels - #289

Open
DMZ22 wants to merge 1 commit into
quarkfin:masterfrom
DMZ22:fix-tick-labels-fixedformatter
Open

Pin tick locations before setting rotated tick labels#289
DMZ22 wants to merge 1 commit into
quarkfin:masterfrom
DMZ22:fix-tick-labels-fixedformatter

Conversation

@DMZ22

@DMZ22 DMZ22 commented Jul 24, 2026

Copy link
Copy Markdown

Closes #157.

In AxisTickLabelsDecorator.decorate() the if self._rotation: branch calls set_ticklabels() with no preceding set_ticks(), while the elif self._tick_values is None: branch immediately below it does call it. Setting labels installs a FixedFormatter, and pairing that with the default non-fixed locator is what matplotlib warns about.

The warning is understating it — the labels end up on the wrong positions. With three labels on an axis using the default locator:

before:  labels ['alpha', 'beta', 'gamma', '', '', '', '', '', '', '', '']
         ticks  [-0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25]

after:   labels ['alpha', 'beta', 'gamma']
         ticks  [0, 1, 2]

matplotlib keeps its eleven auto-generated tick positions and attaches the three labels to the first three of them, so alpha renders at x=-0.25 rather than x=0 and eight blank ticks trail after it. That is a mislabelled axis, not just a noisy log line.

The fix mirrors what the branch below already does — set the ticks first when no explicit tick_values were supplied.

Both affected call paths are live: create_return_quantiles.py:65 constructs the decorator with a rotation and no tick values (that is demo_scripts/charts/return_quantiles_chart.py, the reproduction named in the issue), and heatmap_demo.py reaches it via rotation='auto'.

Tests. There was no plotting test package under qf_lib/tests/unit_tests/, so I added one with test_axis_tick_labels_decorator.py. It covers the two rotation paths, the non-rotated path, the explicit-tick_values path, and an assertion that the rotated labels are still applied to the right ticks at the right angle.

Reverting only the decorator while keeping the tests fails three of the five — including the "labels are still applied" one, which is the correctness half. The other two pass either way by design, since their job is to confirm the already-correct branches are untouched.

Verified on Python 3.11 with the versions requirements.txt pins (numpy 1.26.4, matplotlib 3.6.1). flake8 is clean on both files.

AxisTickLabelsDecorator.decorate() called set_ticklabels() in the rotation
branch without first calling set_ticks(), which installs a FixedFormatter
over the default non-fixed locator. The elif branch below it already gets
this right.

The result is worse than the UserWarning suggests: matplotlib keeps its
auto-generated tick positions and attaches the labels to the first few of
them, so on a three-label chart "alpha" lands at x=-0.25 and eight blank
ticks follow. Setting the ticks first puts the labels back on the
positions they describe.
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.

[Bug]: User Warning during boxplot creation (FixedFormatter)

1 participant