Skip to content

Commit

Permalink
Don't use offset / scientific notation in numeric legends (#3187)
Browse files Browse the repository at this point in the history
* Don't show offset / scientific notation in numeric legends

* Update release notes
  • Loading branch information
mwaskom authored Dec 18, 2022
1 parent 22cdfb0 commit 9bd1665
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/whatsnew/v0.12.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ v0.12.2 (Unreleased)

- |Enhancement| Automatic mark widths are now calculated separately for unshared facet axes (:pr:`3119`).

- |Fix| Fixed a bug where legends for numeric variables with large values with be incorrectly shown (i.e. with a missing offset or exponent; :pr:`3187`).

- |Fix| Fixed a regression in v0.12.0 where manually-added labels could have duplicate legend entries (:pr:`3116`).

- |Fix| Fixed a bug in :func:`histplot` with `kde=True` and `log_scale=True` where the curve was not scaled properly (:pr:`3173`).
Expand Down
8 changes: 8 additions & 0 deletions seaborn/_core/scales.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,14 @@ def spacer(x):
axis.set_view_interval(vmin, vmax)
locs = axis.major.locator()
locs = locs[(vmin <= locs) & (locs <= vmax)]
# Avoid having an offset / scientific notation in a legend
# as we don't represent that anywhere so it ends up incorrect.
# This could become an option (e.g. Continuous.label(offset=True))
# in which case we would need to figure out how to show it.
if hasattr(axis.major.formatter, "set_useOffset"):
axis.major.formatter.set_useOffset(False)
if hasattr(axis.major.formatter, "set_scientific"):
axis.major.formatter.set_scientific(False)
labels = axis.major.formatter.format_ticks(locs)
new._legend = list(locs), list(labels)

Expand Down
4 changes: 4 additions & 0 deletions seaborn/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,10 @@ def get_view_interval(self):
formatter = mpl.ticker.LogFormatter()
else:
formatter = mpl.ticker.ScalarFormatter()
# Avoid having an offset/scientific notation which we don't currently
# have any way of representing in the legend
formatter.set_useOffset(False)
formatter.set_scientific(False)
formatter.axis = dummy_axis()

# TODO: The following two lines should be replaced
Expand Down
9 changes: 9 additions & 0 deletions tests/_core/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,15 @@ def _legend_artist(self, variables, value, scales):
p = Plot(**xy, color=["a", "b", "c", "d"]).add(NoLegendMark()).plot()
assert not p._figure.legends

def test_legend_has_no_offset(self, xy):

color = np.add(xy["x"], 1e8)
p = Plot(**xy, color=color).add(MockMark()).plot()
legend = p._figure.legends[0]
assert legend.texts
for text in legend.texts:
assert float(text.get_text()) > 1e7


class TestDefaultObject:

Expand Down
6 changes: 6 additions & 0 deletions tests/test_relational.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,12 @@ def test_ax_kwarg_removal(self, long_df):
assert len(ax.collections) == 0
assert len(g.ax.collections) > 0

def test_legend_has_no_offset(self, long_df):

g = relplot(data=long_df, x="x", y="y", hue=long_df["z"] + 1e8)
for text in g.legend.texts:
assert float(text.get_text()) > 1e7


class TestLinePlotter(SharedAxesLevelTests, Helpers):

Expand Down

0 comments on commit 9bd1665

Please sign in to comment.