Skip to content
Draft
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
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Checkout our examples
=====================

Below is a gallery showing random examples of what UltraPlot can do, for more examples checkout our extensive `docs <https://ultraplot.readthedocs.io>`_.
View the full gallery here: `Gallery <https://ultraplot.readthedocs.io/en/latest/gallery/index.html>`_.

.. list-table::
:widths: 33 33 33
Expand Down
58 changes: 58 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,64 @@
max-height: calc(100vh - 150px);
}

.gallery-filter-controls {
margin: 1rem 0 2rem;
padding: 1rem 1.2rem;
border-radius: 16px;
background: linear-gradient(
135deg,
rgba(41, 128, 185, 0.08),
rgba(41, 128, 185, 0.02)
);
box-shadow:
0 10px 24px rgba(41, 128, 185, 0.18),
0 2px 6px rgba(41, 128, 185, 0.08);
}

.gallery-filter-bar {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 1rem;
}

.gallery-filter-button {
border: 1px solid #c5c5c5;
background-color: #ffffff;
color: #333333;
padding: 0.35rem 0.85rem;
border-radius: 999px;
font-size: 0.9em;
cursor: pointer;
transition:
background-color 0.2s ease,
color 0.2s ease,
border-color 0.2s ease;
}

.gallery-filter-button.is-active {
background-color: #2980b9;
border-color: #2980b9;
color: #ffffff;
}

.gallery-section-hidden {
display: none;
}

section#layouts > h1,
section#layouts > p,
section#legends-and-colorbars > h1,
section#legends-and-colorbars > p,
section#geoaxes > h1,
section#geoaxes > p,
section#plot-types > h1,
section#plot-types > p,
section#colors-and-cycles > h1,
section#colors-and-cycles > p {
display: none;
}

/* Responsive adjustments */
@media screen and (max-width: 1200px) {
.right-toc {
Expand Down
158 changes: 147 additions & 11 deletions docs/_static/custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {

const tocList = toc.querySelector(".right-toc-list");
const tocContent = toc.querySelector(".right-toc-content");
const tocToggleBtn = toc.querySelector(
".right-toc-toggle-btn",
);
const tocToggleBtn = toc.querySelector(".right-toc-toggle-btn");

// Set up the toggle button
tocToggleBtn.addEventListener("click", function () {
Expand Down Expand Up @@ -118,8 +116,7 @@ document.addEventListener("DOMContentLoaded", function () {

link.textContent = headerText.trim();
link.className =
"right-toc-link right-toc-level-" +
header.tagName.toLowerCase();
"right-toc-link right-toc-level-" + header.tagName.toLowerCase();

item.appendChild(link);
tocList.appendChild(item);
Expand All @@ -141,9 +138,7 @@ document.addEventListener("DOMContentLoaded", function () {
let smallestDistanceFromTop = Infinity;

headerElements.forEach((header) => {
const distance = Math.abs(
header.getBoundingClientRect().top,
);
const distance = Math.abs(header.getBoundingClientRect().top);
if (distance < smallestDistanceFromTop) {
smallestDistanceFromTop = distance;
currentSection = header.id;
Expand All @@ -152,9 +147,7 @@ document.addEventListener("DOMContentLoaded", function () {

tocLinks.forEach((link) => {
link.classList.remove("active");
if (
link.getAttribute("href") === `#${currentSection}`
) {
if (link.getAttribute("href") === `#${currentSection}`) {
link.classList.add("active");
}
});
Expand All @@ -163,6 +156,149 @@ document.addEventListener("DOMContentLoaded", function () {
}
});

document.addEventListener("DOMContentLoaded", function () {
const galleryRoot = document.querySelector("#ultraplot-gallery");
if (galleryRoot) {
const gallerySections = [
"layouts",
"legends-and-colorbars",
"geoaxes",
"plot-types",
"colors-and-cycles",
];
gallerySections.forEach((sectionId) => {
const heading = document.querySelector(
`section#${sectionId} > h1, section#${sectionId} > h2`,
);
if (heading) {
heading.classList.add("no-toc");
}
});
}

const thumbContainers = Array.from(
document.querySelectorAll(".sphx-glr-thumbcontainer"),
);
if (thumbContainers.length < 6) {
return;
}

const topicMap = {
layouts: { label: "Layouts", slug: "layouts" },
"legends and colorbars": {
label: "Legends & Colorbars",
slug: "legends-colorbars",
},
geoaxes: { label: "GeoAxes", slug: "geoaxes" },
"plot types": { label: "Plot Types", slug: "plot-types" },
"colors and cycles": { label: "Colors", slug: "colors" },
};

const topics = [];
const topicOrder = new Set();
const originalSections = new Set();

function normalize(text) {
return text
.toLowerCase()
.replace(/[^\w\s-]/g, "")
.replace(/\s+/g, " ")
.trim();
}

thumbContainers.forEach((thumb) => {
const section = thumb.closest("section");
const heading = section ? section.querySelector("h1, h2") : null;
const key = heading ? normalize(heading.textContent || "") : "";
const info = topicMap[key] || { label: "Other", slug: "other" };
thumb.dataset.topic = info.slug;
if (section) {
originalSections.add(section);
}
if (!topicOrder.has(info.slug) && info.slug !== "other") {
topicOrder.add(info.slug);
topics.push(info);
}
});

if (topics.length === 0) {
return;
}

const firstSection = thumbContainers[0].closest("section");
const parent =
(firstSection && firstSection.parentNode) ||
document.querySelector(".rst-content");
if (!parent) {
return;
}

const controls = document.createElement("div");
controls.className = "gallery-filter-controls";

const filterBar = document.createElement("div");
filterBar.className = "gallery-filter-bar";

function makeButton(label, slug) {
const button = document.createElement("button");
button.type = "button";
button.className = "gallery-filter-button";
button.textContent = label;
button.dataset.topic = slug;
return button;
}

const buttons = [
makeButton("All", "all"),
...topics.map((topic) => makeButton(topic.label, topic.slug)),
];

const counts = {};
thumbContainers.forEach((thumb) => {
const topic = thumb.dataset.topic || "other";
counts[topic] = (counts[topic] || 0) + 1;
});
counts.all = thumbContainers.length;

buttons.forEach((button) => {
const topic = button.dataset.topic;
const count = counts[topic] || 0;
button.textContent = `${button.textContent} (${count})`;
filterBar.appendChild(button);
});

const unified = document.createElement("div");
unified.className = "sphx-glr-thumbnails gallery-unified";
thumbContainers.forEach((thumb) => unified.appendChild(thumb));

controls.appendChild(filterBar);
controls.appendChild(unified);
parent.insertBefore(controls, firstSection);

originalSections.forEach((section) => {
section.classList.add("gallery-section-hidden");
});
document.body.classList.add("gallery-filter-active");

function setFilter(slug) {
buttons.forEach((button) => {
button.classList.toggle("is-active", button.dataset.topic === slug);
});
thumbContainers.forEach((thumb) => {
const matches = slug === "all" || thumb.dataset.topic === slug;
thumb.style.display = matches ? "" : "none";
});
}

buttons.forEach((button) => {
button.addEventListener("click", () => {
setFilter(button.dataset.topic);
});
});

setFilter("all");
});

// Debounce function to limit scroll event firing
function debounce(func, wait) {
let timeout;
Expand Down
47 changes: 44 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ def __getattr__(self, name):

# Print available system fonts
from matplotlib.font_manager import fontManager
from sphinx_gallery.sorting import ExplicitOrder, FileNameSortKey


def _reset_ultraplot(gallery_conf, fname):
"""
Reset UltraPlot rc state between gallery examples.
"""
try:
import ultraplot as uplt
except Exception:
return
uplt.rc.reset()


# -- Project information -------------------------------------------------------
# The basic info
Expand Down Expand Up @@ -144,6 +157,7 @@ def __getattr__(self, name):
"sphinx_copybutton", # add copy button to code
"_ext.notoc",
"nbsphinx", # parse rst books
"sphinx_gallery.gen_gallery",
]


Expand All @@ -165,6 +179,11 @@ def __getattr__(self, name):
"_templates",
"_themes",
"*.ipynb",
"gallery/**/*.codeobj.json",
"gallery/**/*.ipynb",
"gallery/**/*.md5",
"gallery/**/*.py",
"gallery/**/*.zip",
"**.ipynb_checkpoints" ".DS_Store",
"trash",
"tmp",
Expand Down Expand Up @@ -290,6 +309,28 @@ def __getattr__(self, name):

nbsphinx_execute = "auto"

# Sphinx gallery configuration
sphinx_gallery_conf = {
"doc_module": ("ultraplot",),
"examples_dirs": ["examples"],
"gallery_dirs": ["gallery"],
"filename_pattern": r"^((?!sgskip).)*$",
"min_reported_time": 1,
"plot_gallery": "True",
"reset_modules": ("matplotlib", "seaborn", _reset_ultraplot),
"subsection_order": ExplicitOrder(
[
"examples/layouts",
"examples/legends_colorbars",
"examples/geo",
"examples/plot_types",
"examples/colors",
]
),
"within_subsection_order": FileNameSortKey,
"nested_sections": False,
}

# The name of the Pygments (syntax highlighting) style to use.
# The light-dark theme toggler overloads this, but set default anyway
pygments_style = "none"
Expand All @@ -309,13 +350,11 @@ def __getattr__(self, name):
# html_theme = "sphinx_rtd_theme"
html_theme_options = {
"logo_only": True,
"display_version": False,
"collapse_navigation": True,
"navigation_depth": 4,
"prev_next_buttons_location": "bottom", # top and bottom
"includehidden": True,
"titles_only": True,
"display_toc": True,
"sticky_navigation": True,
}

Expand All @@ -330,7 +369,9 @@ def __getattr__(self, name):
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
# html_sidebars = {}
html_sidebars = {
"gallery/index": ["globaltoc.html", "searchbox.html"],
}

# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
Expand Down
6 changes: 6 additions & 0 deletions docs/examples/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
UltraPlot Gallery
=================

Curated examples that highlight what UltraPlot does beyond base Matplotlib:
complex layouts, advanced legends and colorbars, GeoAxes, and specialized plot types.
Each script renders a publication-style figure and becomes a gallery entry.
Loading