> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tablixhq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python

> The built-in in-browser Python editor, supported libraries, and the sheet bridge API.

Tablix includes a full Python code editor and execution engine that runs **entirely in your browser** — no server round-trip needed to execute your code (only the AI code-generation step calls out to the AI service).

## Opening the Python Editor

Open the code editor sidebar and choose **Python** as the language (you can switch between Python and SQL). It's a Monaco-based editor (the same engine behind VS Code), with:

* Syntax highlighting and autocomplete (keywords, built-ins, `pandas`/`numpy`/`scikit-learn`/`scipy` import snippets, and your sheet's actual column headers as suggestions)
* Inline error markers pointing at the failing line
* A resizable console panel showing `print()` output, tables, and errors
* Dark mode toggle
* An AI prompt box inside the editor so you can ask the AI to write the code for you without leaving the editor
* A prompt "optimizer" that rewrites a rough request into a more precise technical instruction before generating code

## Execution Engine

Python code runs via **Pyodide** (CPython compiled to WebAssembly) in a background Web Worker, so it doesn't freeze the UI.

<Info>
  **Available libraries:** `pandas` (as `pd`), `numpy` (as `np`), `scikit-learn` (`sklearn`), `scipy`.

  Other libraries (e.g. `matplotlib`, `seaborn`) are **not** available — charts are created via the `create_chart()` bridge function instead. See [Charts](/charts).
</Info>

## Reading Your Sheet: `q.cells()`

```python theme={null}
import pandas as pd

# Load a range as a DataFrame (headers included by default)
df = q.cells("A:D")        # whole columns A through D
df = q.cells("A1:D50")     # a specific range
```

`q.cells()` automatically loads the requested range from the active sheet into a pandas DataFrame, using the first row of the range as column headers.

## Writing Back to the Sheet

Depending on what you're doing, use the matching bridge function rather than one big generic "set everything" call:

| Function                                                      | Purpose                                                                                                                |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `set_data(data)`                                              | Write a new table (DataFrame, Series, list-of-lists, or scalar) to the sheet — used for aggregations/pivots/new tables |
| `apply_format(rules)`                                         | Apply cell formatting (colors, number formats, bold, borders, etc.) without changing values                            |
| `update_cells(updates)`                                       | Update specific cell values in place, or delete rows, without rebuilding the whole table                               |
| `insert_col(index, header, values)`                           | Insert a new column in place                                                                                           |
| `insert_row(index, values)`                                   | Insert a new row in place                                                                                              |
| `sort_table(col_name_or_index, ascending=True)`               | Sort the existing table in place                                                                                       |
| `apply_filter(col_name_or_index, condition_type, value=None)` | Apply a filter to the existing table in place                                                                          |
| `clear_filter(col_name_or_index=None)`                        | Clear one filter or all filters                                                                                        |
| `create_chart(chart_type, ...)`                               | Create a chart directly on the sheet — see [full reference below](#creating-charts-with-create-chart)                  |

<CodeGroup>
  ```python aggregate.py theme={null}
  import pandas as pd

  df = q.cells("A:C")
  pivot = df.groupby('Region')['Sales'].mean().reset_index()
  set_data(pivot)
  ```

  ```python clean.py theme={null}
  import pandas as pd

  df = q.cells("A:E")
  df = df.dropna(how='all').reset_index(drop=True)

  seen = set()
  updates = []
  for i, row in df.iterrows():
      key = tuple(row)
      if key in seen:
          updates.append({'action': 'delete_row', 'row': i + 1})
      else:
          seen.add(key)
  update_cells(updates)
  ```

  ```python filter_sort.py theme={null}
  apply_filter("Status", "is_equal_to", "Active")
  apply_filter("Price", "greater_than", 100)
  sort_table("Sales", ascending=False)
  ```
</CodeGroup>

<Accordion title="Valid apply_filter condition types">
  `is_equal_to`, `is_not_equal_to`, `text_contains`, `greater_than`, `less_than`, `greater_than_or_equal`, `less_than_or_equal`, `is_empty`, `is_not_empty`, `text_starts_with`, `text_ends_with`, `values` (for matching a list of values).
</Accordion>

## Text Output

Use `print()` for explanations, summaries, or "Key Insights" style analysis instead of `set_data()` — this shows up in the console/chat as text rather than writing a new table to the sheet.

## Creating Charts with `create_chart()`

Use `create_chart()` to build a chart directly from your Python code and place it on the sheet — no `matplotlib`/`seaborn` needed (those libraries aren't available).

```python theme={null}
create_chart(
    chart_type,
    label_col=None,
    value_cols=None,
    agg_func='sum',
    title=None,
    width=600,
    height=370,
    filter_labels=None,
    top_n=None,
    bottom_n=None,
    labels=None,
    values=None,
    series_names=None
)
```

`chart_type` accepts any of Tablix's chart types — `'line'`, `'area'`, `'column'`, `'bar'`, `'pie'`, `'doughnut'`, `'scatter'`, `'radar'`, `'waterfall'`, `'funnel'`, `'combo'`, `'histogram'`, and more. See the full list at [Charts → Chart Types](/charts#chart-types).

### Option 1 — Chart Existing Columns

Point it at columns already on your sheet and let it aggregate for you:

```python theme={null}
create_chart(
    chart_type='column',
    label_col='Region',
    value_cols='Sales',
    agg_func='sum',
    title='Total Sales by Region'
)
```

This groups every row by `Region`, sums `Sales` per group, and charts the result — no need to pre-aggregate with pandas first.

**Multiple value columns** become multiple series:

```python theme={null}
create_chart(
    chart_type='line',
    label_col='Month',
    value_cols=['Revenue', 'Profit'],
    title='Revenue vs Profit by Month'
)
```

**Only the top or bottom N, or specific categories:**

```python theme={null}
# Top 5 products by units sold
create_chart(chart_type='bar', label_col='Product', value_cols='Units Sold', top_n=5)

# Only these specific countries
create_chart(chart_type='pie', label_col='Country', value_cols='Revenue',
              filter_labels=['USA', 'Canada', 'Mexico'])
```

### Option 2 — Chart Data You've Already Computed

If you've already calculated the numbers yourself (e.g. with `pandas.groupby`, or values that don't map to raw columns), pass them directly with `labels` and `values`:

```python theme={null}
import pandas as pd

df = q.cells("A:C")
grouped = df.groupby('Region')['Sales'].sum().sort_values(ascending=False)

create_chart(
    chart_type='column',
    labels=grouped.index.tolist(),
    values=grouped.values.tolist(),
    title='Sales by Region'
)
```

**Multiple series** — pass a list of lists for `values`, with matching `series_names`:

```python theme={null}
create_chart(
    chart_type='line',
    labels=['Jan', 'Feb', 'Mar'],
    values=[[1000, 1200, 900], [700, 650, 800]],
    series_names=['Revenue', 'Cost'],
    title='Revenue vs Cost'
)
```

<Info>
  Use **either** `label_col`/`value_cols` **or** `labels`/`values` — don't mix the two in one call. Placement on the sheet and chart colors are both handled automatically; you don't need to set a position or pick colors yourself.
</Info>

<Tip>
  You don't have to write any of this by hand — describing the chart you want to the [AI Assistant](/ai-assistant) generates the right `create_chart()` call for you. See [Charts → Creating a Chart with AI](/charts#creating-a-chart-with-ai) for prompt examples.
</Tip>

## AI-Generated Python

You don't have to write Python yourself — describe what you want in the [AI Assistant](/ai-assistant) sidebar or the in-editor AI prompt box, and the AI generates the appropriate code using the bridge functions above, then runs it automatically.

<Tip>
  See [Error Handling](/error-handling#python-errors) for a full list of Python error messages and what causes them.
</Tip>
