Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions en/api/cli-swanlab-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,27 +251,29 @@ Get scalar metrics for an experiment, returned as JSON.
swanlab api run metrics <path> --keys <keys> [OPTIONS]
```

| Argument/Option | Type | Default | Description |
| -------------------- | ---------- | -------- | ----------------------------------------------------------------------------------------- |
| `path` | Positional | Required | Experiment path |
| `--keys` | `str` | Required | Comma-separated metric keys, e.g. `"loss,acc"` |
| `--sample` / `-s` | `int` | `1500` | Sample size; auto-capped if exceeded |
| `--ignore-timestamp` | Flag | `False` | Remove timestamp field from metric data |
| `--all` | Flag | `False` | Fetch full data (CSV export for scalars) |
| `--range-type` | `str` | `None` | Range query type: `step` or `timestamp` |
| `--range-start` | `int` | `None` | Range start (inclusive), step number or unix timestamp in ms |
| `--range-end` | `int` | `None` | Range end (inclusive), step number or unix timestamp in ms |
| `--range-head` | `int` | `None` | Return first N data points |
| `--range-tail` | `int` | `None` | Return last N data points |
| `--range-last` | `int` | `None` | Data from the last N milliseconds (mutually exclusive with `--range-start`/`--range-end`) |
| `--save` | Option | — | Save output as JSON file |
| Argument/Option | Type | Default | Description |
| -------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `path` | Positional | Required | Experiment path |
| `--keys` | `str` | Required | Comma-separated metric keys, e.g. `"loss,acc"` |
| `--sample` / `-s` | `int` | `1500` | Sample size; auto-capped if exceeded |
| `--ignore-timestamp` | Flag | `False` | Remove timestamp field from metric data |
| `--all` | Flag | `False` | Fetch full data (CSV export for scalars) |
| `--x-axis` | `str` | `"step"` | X axis of the returned data: `step` (default), built-in axes `time` / `relative_time`, or a custom X-axis metric key (`swanlab >= 0.10.1`) |
| `--range-type` | `str` | `None` | Range query type: `step`, `timestamp`, or `custom` (custom X-axis value domain; requires `--x-axis`) |
| `--range-start` | `float` | `None` | Range start (inclusive), step number, unix timestamp in ms, or custom X-axis value |
| `--range-end` | `float` | `None` | Range end (inclusive), step number, unix timestamp in ms, or custom X-axis value |
| `--range-head` | `int` | `None` | Return first N data points |
| `--range-tail` | `int` | `None` | Return last N data points |
| `--range-last` | `int` | `None` | Data from the last N milliseconds (mutually exclusive with `--range-start`/`--range-end`) |
| `--save` | Option | — | Save output as JSON file |

**Notes:**

- `--range-head` and `--range-tail` are mutually exclusive.
- `--range-last` is mutually exclusive with `--range-start`/`--range-end`.
- `--range-head`/`--range-tail` can be combined with `--range-start`/`--range-end` or `--range-last` (range filter is applied first, then truncation).
- `--range-start` and `--range-end` work with `--range-type` (`step` or `timestamp`); timestamps are in milliseconds.
- `--range-type custom` is only valid when `--x-axis` is a custom metric key; in that case `--range-start`/`--range-end` accept any floats (including negatives). `step` / `timestamp` types require non-negative integers.

```bash
# Get loss metric (default 1500 samples)
Expand All @@ -295,6 +297,14 @@ swanlab api run metrics my-team/image-classification/abc123 \
# Step range + first 50 points
swanlab api run metrics my-team/image-classification/abc123 \
--keys loss --range-type step --range-start 0 --range-end 500 --range-head 50

# Custom X axis: plot loss against epoch
swanlab api run metrics my-team/image-classification/abc123 \
--keys loss --x-axis epoch

# Range filter on the custom X-axis value domain (floats allowed)
swanlab api run metrics my-team/image-classification/abc123 \
--keys loss --x-axis lr --range-type custom --range-start 0.0001 --range-end 0.001
```

### run summary
Expand Down
54 changes: 33 additions & 21 deletions en/api/py-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,24 +393,25 @@ for run in api.runs_get(path="my-team/my-project", page=1, size=100, all=True):

Fetch scalar metric data (e.g. loss, acc), supports sampling control and range queries, returns structured data.

| Parameter | Type | Default | Description |
| ------------------ | ---------------------- | ------- | -------------------------------------------------------------------------- |
| `keys` | `list[str]` | — | Metric key list, e.g. `["loss", "acc"]` |
| `sample` | `int` | `1500` | Sample count (SCALAR max 1500), ignored when `all` or `range_query` is set |
| `all` | `bool` | `False` | Get full data (no sampling limit) |
| `range_query` | `dict` or `RangeQuery` | `None` | Range query, only valid for SCALAR type |
| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields |
| Parameter | Type | Default | Description |
| ------------------ | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `keys` | `list[str]` | — | Metric key list, e.g. `["loss", "acc"]` |
| `sample` | `int` | `1500` | Sample count (SCALAR max 1500), ignored when `all` or `range_query` is set |
| `all` | `bool` | `False` | Get full data (no sampling limit) |
| `range_query` | `dict` or `RangeQuery` | `None` | Range query, only valid for SCALAR type |
| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields |
| `x_axis` | `str` | `"step"` | X axis of the returned data: `"step"` (default), built-in axes `"time"` / `"relative_time"`, or any other non-empty string as a custom X-axis metric key (SCALAR only, `swanlab >= 0.10.1`) |

**RangeQuery fields:**

| Field | Type | Default | Description |
| ------- | ----- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | `str` | `"step"` | Filter axis: `"step"` or `"timestamp"` |
| `start` | `int` | `None` | Lower bound (inclusive), `None` means no limit. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds** |
| `end` | `int` | `None` | Upper bound (inclusive), `None` means up to the last step. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds** |
| `last` | `int` | `None` | Last N milliseconds (mutually exclusive with `start`/`end`) |
| `head` | `int` | `None` | Take first N data points (mutually exclusive with `tail`, applied after range filtering) |
| `tail` | `int` | `None` | Take last N data points (mutually exclusive with `head`, applied after range filtering) |
| Field | Type | Default | Description |
| ------- | ----- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | `str` | `"step"` | Filter axis: `"step"`, `"timestamp"`, or `"custom"` (filters on the custom X-axis value domain; only valid when `x_axis` is a custom metric key) |
| `start` | `int` | `None` | Lower bound (inclusive), `None` means no limit. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds**; when `type` is `custom`, any float is allowed (including negatives) |
| `end` | `int` | `None` | Upper bound (inclusive), `None` means up to the last step. When `type` is `timestamp`, **input must be a UNIX timestamp in milliseconds**; when `type` is `custom`, any float is allowed (including negatives) |
| `last` | `int` | `None` | Last N milliseconds (mutually exclusive with `start`/`end`) |
| `head` | `int` | `None` | Take first N data points (mutually exclusive with `tail`, applied after range filtering) |
| `tail` | `int` | `None` | Take last N data points (mutually exclusive with `head`, applied after range filtering) |

**Mutual exclusion rules:**

Expand Down Expand Up @@ -478,6 +479,16 @@ result = run.metrics(

# Take last 30 data points
result = run.metrics(keys=["loss"], range_query={"tail": 30})

# Custom X axis: plot loss against epoch (the X-axis metric must have been logged, e.g. defined via swanlab.define_metric)
result = run.metrics(keys=["loss"], x_axis="epoch")

# Range filter on the custom X-axis value domain (floats / negatives allowed)
result = run.metrics(
keys=["loss"],
x_axis="lr",
range_query={"type": "custom", "start": 1e-4, "end": 1e-3},
)
```

:::
Expand Down Expand Up @@ -847,12 +858,13 @@ Represents the list of metric keys under an experiment (recommended in `0.9.0+`,

### Key.metric() parameters

| Parameter | Type | Default | Description |
| ------------------ | ------ | ------- | ------------------------------------------------- |
| `sample` | `int` | `1500` | Sample count (max 1500) |
| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields |
| `media_step` | `int` | `None` | Only effective for MEDIA type, specifies the step |
| `all` | `bool` | `False` | Get full data (no sampling limit) |
| Parameter | Type | Default | Description |
| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sample` | `int` | `1500` | Sample count (max 1500) |
| `ignore_timestamp` | `bool` | `False` | Whether to remove timestamp fields |
| `media_step` | `int` | `None` | Only effective for MEDIA type, specifies the step |
| `all` | `bool` | `False` | Get full data (no sampling limit) |
| `x_axis` | `str` | `"step"` | X axis of the returned data: `"step"` (default), built-in axes `"time"` / `"relative_time"`, or a custom X-axis metric key (SCALAR only, `swanlab >= 0.10.1`) |

### Series / Key method examples

Expand Down
33 changes: 33 additions & 0 deletions en/guide_cloud/experiment_track/log-experiment-metric.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ swanlab.log({"train/batch_cost": batch_cost})
swanlab.log({"val/acc": acc})
```

:::tip
For metric names with multiple `/` separators, the current strategy uses the last separator.
For example, a metric named `a/b/c` is grouped under `a/b` by default.
If you need a custom group name, you can define it via [swanlab.define_metric()](../../api/py-define_metric.md) before the metric is logged.
:::

## Specify the Step for Logging

When the logging frequency of some metrics is inconsistent but you want their steps to be aligned, you can achieve alignment by setting the `step` parameter of `swanlab.log`:
Expand Down Expand Up @@ -119,3 +125,30 @@ swanlab.finish()
```

`swanlab.async_log()` supports multiple execution modes (`threading`, `asyncio`, `spawn`). For detailed usage and all mode options, see the [async_log API documentation](../../api/py-async-log.md).

## Custom X Axis

:::info
`swanlab.define_metric()` requires SwanLab SDK **v0.10.0 or higher**.
:::

By default, metric charts use step as the X axis. In some training scenarios (e.g., you want to view metric changes by epoch, learning rate, etc.), you can use `swanlab.define_metric()` to associate a chart's X axis with another metric:

```python
import swanlab

swanlab.init(project="my-project")

# Use train/epoch as the X axis of train/loss
swanlab.define_metric("train/loss", x_axis="train/epoch")

for epoch in range(num_epochs):
# Log the X-axis metric first
swanlab.log({"train/epoch": epoch})
# ... training ...
swanlab.log({"train/loss": loss})
```

X-axis and Y-axis metrics can be logged separately — the SDK automatically fills in the most recent X value for each Y value. The `key` also supports glob batch matching (e.g., `train/*`), making it easy to define the X axis for a group of metrics at once.

For detailed parameter descriptions and notes on custom X axes, see the [define_metric API documentation](../../api/py-define_metric.md).
11 changes: 11 additions & 0 deletions en/guide_cloud/general/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ Upgrade to latest version: `pip install -U swanlab`
Github: https://github.com/SwanHubX/SwanLab
:::

## v0.10.1 - 2026.09.22

**🚀 New Features**

- `OpenAPI/CLI` now supports a custom X-axis parameter when querying experiment metrics

**🔧 Bug Fixes**

- Fixed an issue where the writability probe could trigger an IO error on network file systems such as FUSE
- Fixed an issue where experiment metrics synced via `swanlab sync` in `offline` mode were not visible on the frontend charts

## v0.10.0 - 2026.09.01

**🚀 New Features**
Expand Down
Loading
Loading