Skill Tracer
Skills › Scientific Agent Skills › vaex › visualization.md

visualization.md

105 lines · skills/vaex/references/visualization.md at 5f2bc03

Open on GitHub
1# Visualization without full-data arrays
2
3Vaex can aggregate all eligible rows into a small grid; resolution and range still
4hide within-bin detail and excluded observations. A density plot is not a lossless
5representation. Sources: [Vaex plotting](https://vaex.io/docs/guides/advanced_plotting.html)
6and [Matplotlib API removal](https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.9.0.html).
7

Visualization without full-data arrays

Vaex can aggregate all eligible rows into a small grid; resolution and range still hide within-bin detail and excluded observations. A density plot is not a lossless representation. Sources: Vaex plotting and Matplotlib API removal.

Raw lines 1 to 7
8## Current compatibility and supported names
9
10`df.viz.histogram`, `df.viz.heatmap`, and `df.viz.scatter` are the supported accessor
11names. `plot1d`/`plot` are deprecated aliases. Use `what='mean(z)'`, `'std(z)'`,
12`'sum(z)'`, or `'count(*)'`; calling `df.z.mean()` first produces a scalar, not a
13binned statistic instruction. A 1D histogram uses `.histogram`, not a one-axis heatmap.
15**Verified limitation:** core 4.19.0's default heatmap reduction calls removed
16`matplotlib.cm.get_cmap`, raising `AttributeError` under Matplotlib 3.11.2. An old
17plotting environment may run it, but was not tested here. Use the executed grid
18recipe below with current Matplotlib; do not patch global Matplotlib functions silently.
19The high-level heatmap also does not accept generic `ax=`, `dpi=`, or `alpha=` kwargs.

Current compatibility and supported names

df.viz.histogram, df.viz.heatmap, and df.viz.scatter are the supported accessor names. plot1d/plot are deprecated aliases. Use what='mean(z)', 'std(z)', 'sum(z)', or 'count(*)'; calling df.z.mean() first produces a scalar, not a binned statistic instruction. A 1D histogram uses .histogram, not a one-axis heatmap.

Verified limitation: core 4.19.0's default heatmap reduction calls removed matplotlib.cm.get_cmap, raising AttributeError under Matplotlib 3.11.2. An old plotting environment may run it, but was not tested here. Use the executed grid recipe below with current Matplotlib; do not patch global Matplotlib functions silently. The high-level heatmap also does not accept generic ax=, dpi=, or alpha= kwargs.

Raw lines 8 to 20
21## Histogram and bounded scatter
23```python
24import numpy as np
25import vaex
26import matplotlib.pyplot as plt
28rng = np.random.default_rng(7)
29x = rng.normal(size=1000)
30y = 0.5 * x + rng.normal(size=1000)
31df = vaex.from_arrays(x=x, y=y, z=x + y)
32plt.figure(figsize=(6, 4))
33df.viz.histogram('x', limits=[-4, 4], shape=32, show=False,
34 xlabel='x (arbitrary units)', ylabel='Count')
35plt.savefig('vaex-histogram.png', dpi=120, bbox_inches='tight')
36plt.close()
37sample = df.sample(n=100, random_state=7)
38plt.figure(figsize=(6, 4))
39sample.viz.scatter('x', 'y', s=8, alpha=0.6)
40plt.xlabel('x (arbitrary units)')
41plt.ylabel('y (arbitrary units)')
42plt.savefig('vaex-scatter.png', dpi=120, bbox_inches='tight')
43plt.close()
44```
46Always bound rows before conversion: `df[:1000].x.to_numpy()`, not
47`df.x.values[:1000]`, which evaluates the full column first. A scatter plot is a
48sample; state how it was selected. Higher image DPI does not add information to a grid.

Histogram and bounded scatter

import numpy as np
import vaex
import matplotlib.pyplot as plt

rng = np.random.default_rng(7)
x = rng.normal(size=1000)
y = 0.5 * x + rng.normal(size=1000)
df = vaex.from_arrays(x=x, y=y, z=x + y)
plt.figure(figsize=(6, 4))
df.viz.histogram('x', limits=[-4, 4], shape=32, show=False,
                 xlabel='x (arbitrary units)', ylabel='Count')
plt.savefig('vaex-histogram.png', dpi=120, bbox_inches='tight')
plt.close()
sample = df.sample(n=100, random_state=7)
plt.figure(figsize=(6, 4))
sample.viz.scatter('x', 'y', s=8, alpha=0.6)
plt.xlabel('x (arbitrary units)')
plt.ylabel('y (arbitrary units)')
plt.savefig('vaex-scatter.png', dpi=120, bbox_inches='tight')
plt.close()

Always bound rows before conversion: df[:1000].x.to_numpy(), not df.x.values[:1000], which evaluates the full column first. A scatter plot is a sample; state how it was selected. Higher image DPI does not add information to a grid.

Raw lines 21 to 49
50## Count and mean grids with correct coordinates
52```python
53limits = [[-4., 4.], [-4., 4.]]
54shape = (32, 24) # x bins, y bins
55count_task = df.count(binby=['x', 'y'], limits=limits, shape=shape, delay=True)
56mean_task = df.mean('z', binby=['x', 'y'], limits=limits, shape=shape, delay=True)
57df.execute()
58counts, means = count_task.get(), mean_task.get()
59in_range = ((df.x >= -4) & (df.x < 4) & (df.y >= -4) & (df.y < 4))
60retained = int(df.count(selection=in_range))
61assert int(counts.sum()) == retained
62x_edges = np.linspace(*limits[0], shape[0] + 1)
63y_edges = np.linspace(*limits[1], shape[1] + 1)
64fig, axes = plt.subplots(1, 2, figsize=(10, 4), constrained_layout=True)
65count_image = axes[0].pcolormesh(x_edges, y_edges, np.log10(counts.T + 1),
66 shading='flat', cmap='viridis')
67mean_image = axes[1].pcolormesh(x_edges, y_edges, np.ma.masked_where(counts.T == 0, means.T),
68 shading='flat', cmap='coolwarm')
69fig.colorbar(count_image, ax=axes[0], label='log10(count + 1)')
70fig.colorbar(mean_image, ax=axes[1], label='Mean z (arbitrary units)')
71for ax in axes:
72 ax.set(xlabel='x (arbitrary units)', ylabel='y (arbitrary units)')
73axes[0].set_title(f'Count: {retained}/{len(df)} rows within limits')
74axes[1].set_title('Mean z; empty bins masked')
75fig.savefig('vaex-grids.png', dpi=120, bbox_inches='tight')
76plt.close(fig)
77```
79Vaex grid order follows `binby`: transpose for plotting rows=y, columns=x.
80`pcolormesh` receives edges. For contours/quiver compute centers as
81`(edges[:-1] + edges[1:]) / 2`; endpoints are not centers. Supply the same grid/limits
82to every layer. Mean vectors show averaged components, not individually observed paths.
84`limits='99.7%'` is a percentile range, not a universal three-standard-deviation or
85confidence interval rule. Report exclusions; use prespecified/common limits and color
86scales for comparisons. Means in sparsely populated bins may be unstable: retain counts
87and mask according to a justified count threshold. Show zero counts distinctly from
88missing means. Saving PDF/SVG does not make raster heatmap cells infinite-resolution data.

Count and mean grids with correct coordinates

limits = [[-4., 4.], [-4., 4.]]
shape = (32, 24)  # x bins, y bins
count_task = df.count(binby=['x', 'y'], limits=limits, shape=shape, delay=True)
mean_task = df.mean('z', binby=['x', 'y'], limits=limits, shape=shape, delay=True)
df.execute()
counts, means = count_task.get(), mean_task.get()
in_range = ((df.x >= -4) & (df.x < 4) & (df.y >= -4) & (df.y < 4))
retained = int(df.count(selection=in_range))
assert int(counts.sum()) == retained
x_edges = np.linspace(*limits[0], shape[0] + 1)
y_edges = np.linspace(*limits[1], shape[1] + 1)
fig, axes = plt.subplots(1, 2, figsize=(10, 4), constrained_layout=True)
count_image = axes[0].pcolormesh(x_edges, y_edges, np.log10(counts.T + 1),
                                 shading='flat', cmap='viridis')
mean_image = axes[1].pcolormesh(x_edges, y_edges, np.ma.masked_where(counts.T == 0, means.T),
                                shading='flat', cmap='coolwarm')
fig.colorbar(count_image, ax=axes[0], label='log10(count + 1)')
fig.colorbar(mean_image, ax=axes[1], label='Mean z (arbitrary units)')
for ax in axes:
    ax.set(xlabel='x (arbitrary units)', ylabel='y (arbitrary units)')
axes[0].set_title(f'Count: {retained}/{len(df)} rows within limits')
axes[1].set_title('Mean z; empty bins masked')
fig.savefig('vaex-grids.png', dpi=120, bbox_inches='tight')
plt.close(fig)

Vaex grid order follows binby: transpose for plotting rows=y, columns=x. pcolormesh receives edges. For contours/quiver compute centers as (edges[:-1] + edges[1:]) / 2; endpoints are not centers. Supply the same grid/limits to every layer. Mean vectors show averaged components, not individually observed paths.

limits='99.7%' is a percentile range, not a universal three-standard-deviation or confidence interval rule. Report exclusions; use prespecified/common limits and color scales for comparisons. Means in sparsely populated bins may be unstable: retain counts and mask according to a justified count threshold. Show zero counts distinctly from missing means. Saving PDF/SVG does not make raster heatmap cells infinite-resolution data.

Raw lines 50 to 89
90## Notebook interactivity: illustrative only
92Optional `vaex-jupyter` 0.9.0 registers `df.widget`; current source exposes:
94```python
95import vaex.jupyter
96histogram_widget = df.widget.histogram('x', limits=[-4, 4])
97heatmap_widget = df.widget.heatmap('x', 'y', limits=[[-4, 4], [-4, 4]], shape=64)
98selection_widget = df.widget.selection_expression(initial_value='x > 0')
99```
101These widgets require a functioning Jupyter frontend and its compatible widget
102extensions; source verification is not browser interaction testing. The old
103`plot_widget`/`scatter_widget` examples are not this accessor's current contract.
104For Plotly/other renderers, send only the aggregated grid plus centers/edges and
105coverage metadata; do not materialize the entire DataFrame to make a heatmap.

Notebook interactivity: illustrative only

Optional vaex-jupyter 0.9.0 registers df.widget; current source exposes:

import vaex.jupyter
histogram_widget = df.widget.histogram('x', limits=[-4, 4])
heatmap_widget = df.widget.heatmap('x', 'y', limits=[[-4, 4], [-4, 4]], shape=64)
selection_widget = df.widget.selection_expression(initial_value='x > 0')

These widgets require a functioning Jupyter frontend and its compatible widget extensions; source verification is not browser interaction testing. The old plot_widget/scatter_widget examples are not this accessor's current contract. For Plotly/other renderers, send only the aggregated grid plus centers/edges and coverage metadata; do not materialize the entire DataFrame to make a heatmap.

Raw lines 90 to 105