Skip to content

Commit 81da888

Browse files
committed
Natural sort layout keys before iteration for stable key order
1 parent 24f226e commit 81da888

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

_plotly_utils/utils.py

+16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import decimal
33
import json as _json
44
import sys
5+
import re
56

67
import pytz
78

@@ -242,3 +243,18 @@ def _decorator(func):
242243
func.__doc__ = func.__doc__.format(**names)
243244
return func
244245
return _decorator
246+
247+
248+
def _natural_sort_strings(vals, reverse=False):
249+
250+
def key(v):
251+
v_parts = re.split(r'(\d+)', v)
252+
for i in range(len(v_parts)):
253+
try:
254+
v_parts[i] = int(v_parts[i])
255+
except ValueError:
256+
# not an int
257+
pass
258+
return tuple(v_parts)
259+
260+
return sorted(vals, key=key, reverse=reverse)

plotly/basedatatypes.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from contextlib import contextmanager
1010
from copy import deepcopy, copy
1111

12+
from _plotly_utils.utils import _natural_sort_strings
1213
from plotly.subplots import (
1314
_set_trace_grid_reference,
1415
_get_grid_subplot,
@@ -810,7 +811,10 @@ def _select_layout_subplots_by_prefix(
810811
else:
811812
container_to_row_col = None
812813

813-
for k in self.layout:
814+
# Natural sort keys so that xaxis20 is after xaxis3
815+
layout_keys = _natural_sort_strings(list(self.layout))
816+
817+
for k in layout_keys:
814818
if k.startswith(prefix) and self.layout[k] is not None:
815819

816820
# Filter by row/col

0 commit comments

Comments
 (0)