Skip to content

Commit 4cbd237

Browse files
committed
Refactor: update--> .set_data for more consistent naming scheme.
1 parent 2ef6df0 commit 4cbd237

9 files changed

Lines changed: 74 additions & 49 deletions

File tree

Examples/Benchmarks/plot_benchmark_comparison.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
+---------------+---------------------------------------------------------------+
2727
| Library | What is timed |
2828
+===============+===============================================================+
29-
| anyplotlib | ``plot.update(data)`` — float → uint8 normalise → base64 |
29+
| anyplotlib | ``plot.set_data(data)`` — float → uint8 normalise → base64 |
3030
| | encode → LUT rebuild → state-dict assembly → json.dumps → |
3131
| | traitlet dispatch to JS renderer. |
3232
+---------------+---------------------------------------------------------------+
@@ -228,7 +228,7 @@ def _measure_js_ms_all(pairs, n_warmup=3, n_samples=12):
228228

229229
def _make_apl_update(plot, frames, idx):
230230
def _fn():
231-
plot.update(frames[idx[0] % len(frames)])
231+
plot.set_data(frames[idx[0] % len(frames)])
232232
idx[0] += 1
233233
return _fn
234234

@@ -306,7 +306,7 @@ def _fn():
306306
_new_ys_apl = rng.standard_normal(n_pts).cumsum().astype(np.float32)
307307

308308
def _make_apl1d(plot, new_y):
309-
def _fn(): plot.update(new_y)
309+
def _fn(): plot.set_data(new_y)
310310
return _fn
311311

312312
results_1d["anyplotlib"][n_pts] = _timeit_min_ms(

Examples/Interactive/plot_interactive_fft.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def _roi_released(event):
175175
log_mag, freq_x, freq_y = _compute_fft(image, x0, y0, w, h)
176176

177177
# Push updated FFT into the right panel
178-
v_fft.update(log_mag, x_axis=freq_x, y_axis=freq_y, units="1/\u00c5")
178+
v_fft.set_data(log_mag, x_axis=freq_x, y_axis=freq_y, units="1/\u00c5")
179179

180180

181181
fig

Examples/plot_3d.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@
6363
# %%
6464
# Update the surface data live
6565
# ----------------------------
66-
# Call :meth:`~anyplotlib.figure_plots.Plot3D.update` to replace the geometry
66+
# Call :meth:`~anyplotlib.figure_plots.Plot3D.set_data` to replace the geometry
6767
# without recreating the panel.
6868

6969
ZZ2 = np.cos(np.sqrt(XX ** 2 + YY ** 2))
70-
surf.update(XX, YY, ZZ2)
70+
surf.set_data(XX, YY, ZZ2)
7171
surf.set_colormap("plasma")
7272
surf.set_view(azimuth=30, elevation=40)
7373

Examples/plot_bar.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Vertical and horizontal orientations, per-bar colours, category labels
99
* **Grouped bars** — pass a 2-D *height* array ``(N, G)``
1010
* **Log-scale value axis** — ``log_scale=True``
11-
* Live data updates via :meth:`~anyplotlib.figure_plots.PlotBar.update`
11+
* Live data updates via :meth:`~anyplotlib.figure_plots.PlotBar.set_data`
1212
"""
1313
import numpy as np
1414
import anyplotlib as vw
@@ -117,7 +117,7 @@
117117
# Side-by-side comparison — update data live
118118
# -------------------------------------------
119119
# Place two :class:`~anyplotlib.figure_plots.PlotBar` panels in one figure.
120-
# Call :meth:`~anyplotlib.figure_plots.PlotBar.update` to swap in Q2 data —
120+
# Call :meth:`~anyplotlib.figure_plots.PlotBar.set_data` to swap in Q2 data —
121121
# the value-axis range recalculates automatically.
122122

123123
q1 = np.array([42, 55, 48, 63, 71, 68, 74, 81, 66, 59, 52, 78], dtype=float)
@@ -134,7 +134,7 @@
134134
all_months, q1, width=0.6,
135135
color="#ff7043", show_values=False, y_units="Q2 sales",
136136
)
137-
bar_right.update(q2) # swap in Q2 — axis range recalculates automatically
137+
bar_right.set_data(q2) # swap in Q2 — axis range recalculates automatically
138138

139139
fig5
140140

@@ -206,7 +206,7 @@
206206
# -------------------------------------------
207207
# Place two :class:`~anyplotlib.figure_plots.PlotBar` panels in one
208208
# :func:`~anyplotlib.figure_plots.subplots` figure. Call
209-
# :meth:`~anyplotlib.figure_plots.PlotBar.update` to swap in Q2 data for the
209+
# :meth:`~anyplotlib.figure_plots.PlotBar.set_data` to swap in Q2 data for the
210210
# right panel, demonstrating how the axis range re-calculates automatically.
211211

212212
quarters = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -236,7 +236,7 @@
236236
)
237237

238238
# Swap in Q2 data — range is recalculated automatically
239-
bar_right.update(q2)
239+
bar_right.set_data(q2)
240240

241241
fig3
242242

anyplotlib/figure_plots.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ def __init__(self, data: np.ndarray,
698698
if origin == "lower":
699699
data = np.flipud(data)
700700

701+
self._data: np.ndarray = data.astype(float)
702+
701703
x_axis_given = x_axis is not None
702704
y_axis_given = y_axis is not None
703705
if x_axis is None:
@@ -785,9 +787,20 @@ def to_state_dict(self) -> dict:
785787
return d
786788

787789
# ------------------------------------------------------------------
788-
# Data update
790+
# Data
789791
# ------------------------------------------------------------------
790-
def update(self, data: np.ndarray,
792+
@property
793+
def data(self) -> np.ndarray:
794+
"""The image data in the original user coordinate system (read-only).
795+
796+
Returns a float64 copy with ``writeable=False``. To replace the
797+
data call :meth:`set_data`.
798+
"""
799+
arr = np.flipud(self._data).copy() if self._origin == "lower" else self._data.copy()
800+
arr.flags.writeable = False
801+
return arr
802+
803+
def set_data(self, data: np.ndarray,
791804
x_axis=None, y_axis=None, units: str | None = None) -> None:
792805
"""Replace the image data.
793806
@@ -804,6 +817,7 @@ def update(self, data: np.ndarray,
804817
if self._origin == "lower":
805818
data = np.flipud(data)
806819

820+
self._data = data.astype(float)
807821
img_u8, vmin, vmax = _normalize_image(data)
808822
self._raw_u8, self._raw_vmin, self._raw_vmax = img_u8, vmin, vmax
809823

@@ -1278,9 +1292,9 @@ def __init__(self, data: np.ndarray,
12781292
allowed=MarkerRegistry._KNOWN_MESH)
12791293

12801294
# ------------------------------------------------------------------
1281-
# Data update
1295+
# Data
12821296
# ------------------------------------------------------------------
1283-
def update(self, data: np.ndarray,
1297+
def set_data(self, data: np.ndarray,
12841298
x_edges=None, y_edges=None, units: str | None = None) -> None:
12851299
"""Replace the mesh data (and optionally the edge arrays)."""
12861300
data = np.asarray(data)
@@ -1535,7 +1549,7 @@ def set_zoom(self, zoom: float) -> None:
15351549
self._state["zoom"] = float(zoom)
15361550
self._push()
15371551

1538-
def update(self, x, y, z) -> None:
1552+
def set_data(self, x, y, z) -> None:
15391553
"""Replace the geometry data."""
15401554
# Re-run the same logic as __init__ for the stored geom_type
15411555
geom_type = self._state["geom_type"]
@@ -1856,9 +1870,20 @@ def on_primary_click(event):
18561870
return Line1D(self, None)
18571871

18581872
# ------------------------------------------------------------------
1859-
# Data update
1873+
# Data
18601874
# ------------------------------------------------------------------
1861-
def update(self, data: np.ndarray, x_axis=None,
1875+
@property
1876+
def data(self) -> np.ndarray:
1877+
"""The primary line's y-data (read-only).
1878+
1879+
Returns a float64 copy with ``writeable=False``. To replace the
1880+
data call :meth:`set_data`.
1881+
"""
1882+
arr = self._state["data"].copy()
1883+
arr.flags.writeable = False
1884+
return arr
1885+
1886+
def set_data(self, data: np.ndarray, x_axis=None,
18621887
units: str | None = None, y_units: str | None = None) -> None:
18631888
"""Replace the primary line's y-data and optionally its x-axis / units.
18641889
@@ -3070,9 +3095,9 @@ def to_state_dict(self) -> dict:
30703095
return d
30713096

30723097
# ------------------------------------------------------------------
3073-
# Data update
3098+
# Data
30743099
# ------------------------------------------------------------------
3075-
def update(self, height, x=None, x_labels=None, *, x_centers=None) -> None:
3100+
def set_data(self, height, x=None, x_labels=None, *, x_centers=None) -> None:
30763101
"""Replace bar heights; recalculates the value-axis range automatically.
30773102
30783103
Parameters

tests/test_bar.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Range / padding calculations
1515
* Grouped bars – 2-D height array, group_labels, group_colors
1616
* Log scale – log_scale flag, clamping, set_log_scale()
17-
* update() – value replacement and axis recalculation
17+
* set_data() – value replacement and axis recalculation
1818
* Display-setting mutations: set_color, set_colors, set_show_values, set_log_scale
1919
* _push() contract – state is propagated to the Figure
2020
* Layout JSON reflects "bar" kind for PlotBar panels
@@ -275,17 +275,17 @@ def test_repr_shows_groups(self):
275275
p = ax.bar([0, 1], [[1, 2], [3, 4]])
276276
assert "groups=2" in repr(p)
277277

278-
def test_update_2d_values(self):
278+
def test_set_data_2d_values(self):
279279
fig, ax = apl.subplots(1, 1)
280280
p = ax.bar(["A", "B"], [[1, 2], [3, 4]])
281-
p.update([[10, 20], [30, 40]])
281+
p.set_data([[10, 20], [30, 40]])
282282
assert _state(p)["values"] == pytest.approx(np.array([[10, 20], [30, 40]]))
283283

284-
def test_update_group_count_mismatch_raises(self):
284+
def test_set_data_group_count_mismatch_raises(self):
285285
fig, ax = apl.subplots(1, 1)
286286
p = ax.bar(["A", "B"], [[1, 2], [3, 4]]) # groups=2
287287
with pytest.raises(ValueError, match="Group count mismatch"):
288-
p.update([[1, 2, 3], [4, 5, 6]]) # 3 groups → error
288+
p.set_data([[1, 2, 3], [4, 5, 6]]) # 3 groups → error
289289

290290

291291
# ─────────────────────────────────────────────────────────────────────────────
@@ -341,55 +341,55 @@ def test_set_log_scale_push(self):
341341

342342

343343
# ─────────────────────────────────────────────────────────────────────────────
344-
# 6. update() — value replacement
344+
# 6. set_data() — value replacement
345345
# ─────────────────────────────────────────────────────────────────────────────
346346

347-
class TestPlotBarUpdate:
347+
class TestPlotBarSetData:
348348

349349
def test_update_replaces_values(self):
350350
p = _make_bar([1, 2, 3])
351-
p.update([10, 20, 30])
351+
p.set_data([10, 20, 30])
352352
assert _state(p)["values"] == pytest.approx(np.array([[10.0], [20.0], [30.0]]))
353353

354354
def test_update_recalculates_data_max(self):
355355
p = _make_bar([1, 2, 3])
356-
p.update([100, 200, 300])
356+
p.set_data([100, 200, 300])
357357
assert _state(p)["data_max"] > 300.0
358358

359359
def test_update_recalculates_data_min(self):
360360
p = _make_bar([1, 2, 3])
361-
p.update([-50, -20, -10])
361+
p.set_data([-50, -20, -10])
362362
assert _state(p)["data_min"] < -50.0
363363

364364
def test_update_with_new_x_centers(self):
365365
p = _make_bar([1, 2, 3])
366-
p.update([4, 5, 6], x_centers=[0.5, 1.5, 2.5])
366+
p.set_data([4, 5, 6], x_centers=[0.5, 1.5, 2.5])
367367
assert _state(p)["x_centers"] == pytest.approx([0.5, 1.5, 2.5])
368368

369369
def test_update_with_new_x(self):
370370
p = _make_bar([1, 2, 3])
371-
p.update([4, 5, 6], x=[0.5, 1.5, 2.5])
371+
p.set_data([4, 5, 6], x=[0.5, 1.5, 2.5])
372372
assert _state(p)["x_centers"] == pytest.approx([0.5, 1.5, 2.5])
373373

374374
def test_update_with_new_x_labels(self):
375375
p = _make_bar([1, 2, 3], x_labels=["a", "b", "c"])
376-
p.update([4, 5, 6], x_labels=["x", "y", "z"])
376+
p.set_data([4, 5, 6], x_labels=["x", "y", "z"])
377377
assert _state(p)["x_labels"] == ["x", "y", "z"]
378378

379379
def test_update_preserves_orient(self):
380380
p = _make_bar([1, 2, 3], orient="h")
381-
p.update([4, 5, 6])
381+
p.set_data([4, 5, 6])
382382
assert _state(p)["orient"] == "h"
383383

384384
def test_update_preserves_baseline(self):
385385
p = _make_bar([1, 2, 3], baseline=2.0)
386-
p.update([10, 20, 30])
386+
p.set_data([10, 20, 30])
387387
assert _state(p)["baseline"] == pytest.approx(2.0)
388388

389-
def test_update_3d_raises(self):
389+
def test_set_data_3d_raises(self):
390390
p = _make_bar([1, 2, 3])
391391
with pytest.raises(ValueError, match="1-D or 2-D"):
392-
p.update(np.zeros((2, 2, 2)))
392+
p.set_data(np.zeros((2, 2, 2)))
393393

394394

395395
# ─────────────────────────────────────────────────────────────────────────────
@@ -441,7 +441,7 @@ def test_panel_json_contains_kind_bar(self):
441441
def test_panel_json_values_after_update(self):
442442
fig, ax = apl.subplots(1, 1)
443443
p = ax.bar([1, 2, 3])
444-
p.update([7, 8, 9])
444+
p.set_data([7, 8, 9])
445445
trait_name = f"panel_{p._id}_json"
446446
data = json.loads(getattr(fig, trait_name))
447447
assert data["values"] == pytest.approx(np.array([[7.0], [8.0], [9.0]]))

tests/test_benchmarks_py.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1. ``_normalize_image(data)`` — NumPy cast + min/max + scale + uint8
1414
2. ``Plot2D._encode_bytes(img_u8)`` — base64.b64encode
1515
3. ``json.dumps(plot.to_state_dict())`` — full end-to-end (2D and 1D)
16-
4. ``plot.update(data)`` — complete Python-side round-trip
16+
4. ``plot.set_data(data)`` — complete Python-side round-trip
1717
1818
Workflow
1919
--------
@@ -219,15 +219,15 @@ def test_bench_py_serialize_1d(n_pts, update_benchmarks):
219219

220220

221221
# ---------------------------------------------------------------------------
222-
# Full plot.update() round-trip (normalize + encode + build_lut + push)
222+
# Full plot.set_data() round-trip (normalize + encode + build_lut + push)
223223
# ---------------------------------------------------------------------------
224224

225225
@pytest.mark.parametrize(
226226
"h,w,is_slow", _IMSHOW_SIZES,
227227
ids=[f"{h}x{w}" for h, w, _ in _IMSHOW_SIZES],
228228
)
229-
def test_bench_py_update_2d(h, w, is_slow, update_benchmarks, run_slow):
230-
"""Python: full ``plot.update(data)`` round-trip for a ``{h}×{w}`` image.
229+
def test_bench_py_set_data_2d(h, w, is_slow, update_benchmarks, run_slow):
230+
"""Python: full ``plot.set_data(data)`` round-trip for a ``{h}×{w}`` image.
231231
232232
Covers the complete Python-side cost of a live data refresh:
233233
``_normalize_image`` + ``_encode_bytes`` + ``_build_colormap_lut``
@@ -245,7 +245,7 @@ def test_bench_py_update_2d(h, w, is_slow, update_benchmarks, run_slow):
245245
idx = [0]
246246

247247
def _one_update():
248-
plot.update(frames[idx[0] % len(frames)])
248+
plot.set_data(frames[idx[0] % len(frames)])
249249
idx[0] += 1
250250

251251
timing = _timeit_ms(stmt=_one_update)

tests/test_imshow_params.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,19 @@ def test_lower_flips_data(self):
135135
assert stored[0, :].max() == 255 # top row contains the global max
136136
assert stored[-1, :].min() == 0 # bottom row contains the global min
137137

138-
def test_lower_update_reapplies_flip(self):
139-
"""update() with origin='lower' automatically re-flips new data."""
138+
def test_lower_set_data_reapplies_flip(self):
139+
"""set_data() with origin='lower' automatically re-flips new data."""
140140
fig, ax = apl.subplots()
141141
v = ax.imshow(DATA, origin="lower")
142-
v.update(DATA)
142+
v.set_data(DATA)
143143
stored = _decoded(v)
144144
assert stored[0, :].max() == 255
145145
assert stored[-1, :].min() == 0
146146

147-
def test_lower_update_reverses_new_y_axis(self):
147+
def test_lower_set_data_reverses_new_y_axis(self):
148148
fig, ax = apl.subplots()
149149
v = ax.imshow(DATA, origin="lower")
150-
v.update(DATA, y_axis=Y)
150+
v.set_data(DATA, y_axis=Y)
151151
assert v._state["y_axis"][0] == pytest.approx(40.0)
152152
assert v._state["y_axis"][-1] == pytest.approx(10.0)
153153

tests/test_widgets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ def test_drag_rectangle_updates_fft(self):
588588
def on_rect_changed(event):
589589
log_mag, freq_x, freq_y = self._compute_fft(
590590
img, event.x, event.y, event.w, event.h)
591-
v_fft.update(log_mag, x_axis=freq_x, y_axis=freq_y, units="1/Å")
591+
v_fft.set_data(log_mag, x_axis=freq_x, y_axis=freq_y, units="1/Å")
592592
updates.append({"x": event.x, "y": event.y,
593593
"w": event.w, "h": event.h})
594594

0 commit comments

Comments
 (0)