Skip to main content

nolegend

Remove the legend to become one.

Tufte-style templates and helpers for Plotly. One import, beautiful charts.

Based on Edward Tufte's The Visual Display of Quantitative Information: maximize data-ink ratio, remove chartjunk, direct-label instead of legends, use range frames, and apply colorblind-safe palettes.

Why this exists

There is no Tufte package for Plotly on PyPI. matplotlib has matplotx, plotnine has theme_tufte(), ggplot2 has ggthemes — Plotly has nothing. The closest built-in template (simple_white) removes gridlines but stops there. The default Plotly output is noisy: legends, gridlines, aggressive colors, titles that describe axes instead of insights.

nolegend fills that gap with opinionated defaults and easy overrides.

What this is NOT

  • Not a general visualization framework. Plotly only.
  • Not a dashboard framework. Use marimo for layout.
  • Not a Tufte orthodoxy enforcer. We take the useful parts (data-ink ratio, range frames, direct labeling, small multiples) and skip the dogma.
  • Not a replacement for domain judgment. The library guides chart selection and color use, but the human picks the story.

Install

uv add nolegend

Claude Code skill

nolegend ships a visualization skill that teaches Claude Code the px → go workflow, Tufte principles, color rules, and marimo patterns.

npx skills add mojzis/nolegend

Once installed, Claude Code will automatically apply nolegend conventions whenever you create Plotly charts.

Quick start

import plotly.express as px
import nolegend

nolegend.activate()  # set as default template for all figures

df = px.data.gapminder().query("continent == 'Europe' and year == 2007")
fig = px.bar(df.nlargest(10, "gdpPercap"), x="country", y="gdpPercap")
fig.show()

The px → go workflow

Start fast with Plotly Express, then refine:

import plotly.express as px
import nolegend

# 1. Quick draft with px
fig = px.line(
    df, x="year", y="revenue", color="product",
    template="tufte",
)

# 2. Refine: axes span only the data
nolegend.range_frame(fig)

# 3. Refine: labels on the lines, not in a legend box
nolegend.direct_label(fig)

# 4. Refine: call out the key moment
nolegend.annotate_point(fig, x=2023, y=peak, text="Record quarter")

fig.show()

Color palettes

Six curated, colorblind-safe palettes:

Palette Use case
qualitative Categorical data (default)
ink Grayscale, maximum data-ink
duo Two series (dark + red accent)
earth Business/financial
slate Technical/scientific
sequential Ordered/continuous data
# Use a specific palette
fig = px.line(df, ..., template=nolegend.with_palette("earth"))

# Spotlight: highlight one series, gray out the rest
colors = nolegend.QUALITATIVE.spotlight(index=2)

Hard ceiling of 5 colors per chart. Gray is a deliberate design tool, not a leftover.

Sparklines

Word-sized graphics, inline with text:

spark = nolegend.sparkline([1, 4, 2, 5, 3, 7], width=150, height=30)
spark.show()

Dark mode

nolegend.activate(dark=True)
# or per-figure:
fig = px.scatter(df, ..., template="tufte_dark")

In marimo notebooks

import marimo as mo
import nolegend

# Auto-detect marimo theme
nolegend.activate(dark=mo.app_meta().theme == "dark")

# Reactive plotly charts
fig = px.scatter(df, x="x", y="y", template="tufte")
chart = mo.ui.plotly(fig)

API

Function What it does
activate(dark=False) Set tufte as default template
with_palette(name, dark=False) Register + return template with specific palette
range_frame(fig, pad=0.02) Trim axes to data range
direct_label(fig, position="right") Label lines directly, remove legend
sparkline(values, ...) Create a word-sized trend graphic
annotate_point(fig, x, y, text) Arrow annotation on a data point
strip_chartjunk(fig) Quick cleanup of any Plotly figure

License

MIT

Metadata

Release files for nolegend 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nolegend 0.1.2
File Size Uploaded
nolegend-0.1.2.tar.gz 115.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nolegend 0.1.2
File Interpreter ABI Platform
nolegend-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 124.6 kB

Release files / nolegend-0.1.2.tar.gz

Download URL nolegend-0.1.2.tar.gz
Size 115.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b08a68724a1c9e49de8ef8fa9a713b0ca032945aef84f9b4918dfe0f2cee1c05
BLAKE2b-256 checksum
How to use checksums
534e36609cf6496ea2efa7105ae814f39ab808d399d674af8709aae015168d4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Release files / nolegend-0.1.2-py3-none-any.whl

Download URL nolegend-0.1.2-py3-none-any.whl
Size 9.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40649f4611e7ce502d554a0bf9e3efd34d537d92bfd27be7a44e86fd6f2d7340
BLAKE2b-256 checksum
How to use checksums
1c03c6772f03aa8e713cbd2592bc67efc0b67a179ac8447d23937cca23fde7a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page