Skip to content

Commit aa87805

Browse files
Merge pull request #6 from quarto-dev/renderings-examples
light/dark renderings examples
2 parents b1f8e41 + a10d86a commit aa87805

24 files changed

+3183
-0
lines changed

renderings/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/.quarto/
2+
_site
3+
_site/
4+
*_files/
5+
*.html.md

renderings/_publish.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- source: project
2+
quarto-pub:
3+
- id: a22b69eb-2309-4489-8eb4-6432f489b51f
4+
url: https://examples.quarto.pub/lightdark-renderings-examples

renderings/_quarto.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
project:
2+
type: website
3+
website:
4+
title: "light/dark renderings examples"
5+
sidebar:
6+
style: "docked"
7+
contents:
8+
- altair.qmd
9+
- bokeh.qmd
10+
- flextable.qmd
11+
- ggiraph.qmd
12+
- ggplot.qmd
13+
- great-tables.qmd
14+
- gt.qmd
15+
- heatmaply.qmd
16+
- leaflet.qmd
17+
- matplotlib.qmd
18+
- plotly-python.qmd
19+
- plotly-r.qmd
20+
- plotnine.qmd
21+
- pygal.qmd
22+
- seaborn.qmd
23+
- thematic.qmd
24+
25+
brand:
26+
light: light-brand.yml
27+
dark: dark-brand.yml
28+
29+
theme:
30+
light: brand
31+
dark: [brand, dark-fixups.scss]

renderings/altair.qmd

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
title: altair
3+
engine: jupyter
4+
keep-md: true
5+
---
6+
7+
8+
```{python}
9+
from quarto import theme_brand_altair
10+
import altair as alt
11+
12+
light_theme = theme_brand_altair('light-brand.yml')
13+
dark_theme = theme_brand_altair('dark-brand.yml')
14+
15+
alt.theme.register('light_theme', enable=False)(light_theme)
16+
alt.theme.register('dark_theme', enable=False)(dark_theme);
17+
```
18+
19+
```{python}
20+
#| echo: false
21+
22+
# load a sample dataset as a pandas DataFrame
23+
from vega_datasets import data
24+
cars = data.cars()
25+
_ = alt.renderers.enable('html')
26+
```
27+
28+
### No crossref or caption
29+
30+
```{python}
31+
#| echo: false
32+
#| renderings: [light, dark]
33+
34+
chart = alt.Chart(cars).mark_point().encode(
35+
x='Horsepower',
36+
y='Miles_per_Gallon',
37+
color='Origin',
38+
).properties(width=800, height=500).interactive()
39+
40+
alt.theme.enable('light_theme')
41+
chart.show()
42+
43+
alt.theme.enable('dark_theme')
44+
chart.show()
45+
```
46+
47+
48+
### with crossref but no caption
49+
50+
::: {#fig-altair-hp-year}
51+
52+
```{python}
53+
#| echo: false
54+
#| renderings: [light, dark]
55+
56+
chart = alt.Chart(cars).mark_point().encode(
57+
x='Year',
58+
y='Horsepower',
59+
color='Origin',
60+
).properties(width=800, height=500).interactive()
61+
62+
alt.theme.enable('light_theme')
63+
chart.show()
64+
65+
alt.theme.enable('dark_theme')
66+
chart.show()
67+
```
68+
69+
:::
70+
71+
### caption but no crossref
72+
73+
::: {}
74+
75+
```{python}
76+
#| echo: false
77+
#| renderings: [light, dark]
78+
79+
chart = alt.Chart(cars).mark_point().encode(
80+
x='Horsepower',
81+
y='Acceleration',
82+
color='Origin',
83+
).properties(width=800, height=500).interactive()
84+
85+
alt.theme.enable('light_theme')
86+
chart.show()
87+
88+
alt.theme.enable('dark_theme')
89+
chart.show()
90+
```
91+
92+
cars dataset, acceleration by horsepower
93+
:::
94+
95+
### with crossref and caption
96+
97+
98+
::: {#fig-altair-cars-acc-year}
99+
100+
```{python}
101+
#| echo: false
102+
#| renderings: [light, dark]
103+
104+
chart = alt.Chart(cars).mark_point().encode(
105+
x='Year',
106+
y='Acceleration',
107+
color='Origin',
108+
).properties(width=800, height=500).interactive()
109+
110+
alt.theme.enable('light_theme')
111+
chart.show()
112+
113+
alt.theme.enable('dark_theme')
114+
chart.show()
115+
```
116+
117+
cars dataset, acceleration by year
118+
:::
119+
120+
{{< lipsum 2 >}}

renderings/bokeh.qmd

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: bokeh
3+
author: "anthropic claude-3-5-sonnet-latest"
4+
date: 2025-01-06
5+
---
6+
7+
## Question
8+
9+
How can we create a working scatter plot matrix (SPLOM) of the iris dataset using Bokeh?
10+
11+
## Overview
12+
13+
We’ll create an interactive scatter plot matrix visualization of the iris dataset using Bokeh, with correct color mapping for different species.
14+
15+
Note: Bokeh dark theme helper is incomplete due to lack of documentation (?)
16+
17+
## Code
18+
19+
```{python}
20+
#| echo: false
21+
from quarto import theme_brand_bokeh
22+
23+
light_theme = theme_brand_bokeh('light-brand.yml')
24+
dark_theme = theme_brand_bokeh('dark-brand.yml')
25+
```
26+
27+
```{python}
28+
#| echo: false
29+
#| renderings: [light, dark]
30+
from bokeh.plotting import figure, show
31+
from bokeh.layouts import gridplot
32+
from bokeh.io import output_notebook
33+
from bokeh.sampledata.iris import flowers
34+
from bokeh.models import ColumnDataSource, ColorBar
35+
from bokeh.transform import factor_cmap
36+
37+
# Enable notebook output; hiding banner helps the first plot
38+
# with issue described below
39+
output_notebook(hide_banner=True)
40+
41+
# Create ColumnDataSource for the data
42+
source = ColumnDataSource(flowers)
43+
44+
# Define the features we want to plot
45+
features = ['petal_length', 'petal_width', 'sepal_length', 'sepal_width']
46+
47+
# Create color mapper
48+
color_mapper = factor_cmap('species',
49+
['#1f77b4', '#ff7f0e', '#2ca02c'],
50+
['setosa', 'versicolor', 'virginica'])
51+
52+
# Create the plots matrix
53+
plots = []
54+
tooltips = [
55+
('Species', '@species'),
56+
('Value', '$data_x, $data_y')
57+
]
58+
59+
for i, y in enumerate(features):
60+
row = []
61+
for x in features:
62+
plot = figure(width=200, height=200,
63+
tooltips=tooltips,
64+
title="" if x != features[0] or i != 0 else "Iris SPLOM")
65+
66+
# Add scatter points with proper color mapping
67+
plot.scatter(x, y,
68+
color=color_mapper,
69+
size=8,
70+
alpha=0.5,
71+
legend_field='species',
72+
source=source)
73+
74+
# Configure axes
75+
if i != len(features)-1:
76+
plot.xaxis.visible = False
77+
else:
78+
plot.xaxis.axis_label = x
79+
80+
if x != features[0]:
81+
plot.yaxis.visible = False
82+
else:
83+
plot.yaxis.axis_label = y
84+
85+
# Show legend only on top-right plot
86+
if i != 0 or x != features[-1]:
87+
plot.legend.visible = False
88+
else:
89+
plot.legend.click_policy = "hide"
90+
91+
plot.grid.grid_line_color = None
92+
row.append(plot)
93+
plots.append(row)
94+
95+
# Create and show the grid
96+
grid = gridplot(plots)
97+
98+
light_theme()
99+
show(grid)
100+
101+
dark_theme()
102+
show(grid)
103+
```
104+
105+
Bokeh has issues with emitting extra outputs. Quarto is partly fixing this up but the second plot will currently not work with `renderings`:
106+
107+
```{python}
108+
#| renderings: [light, dark]
109+
light_theme()
110+
show(grid)
111+
112+
dark_theme()
113+
show(grid)
114+
```
115+
116+
## Explanation
117+
118+
This code creates a violin plot of the sepal length distribution for each species in the Iris dataset using Bokeh. Here's a breakdown of what the code does:
119+
120+
1. We start by importing the necessary libraries, including Pandas for data manipulation, NumPy for numerical operations, and various Bokeh modules for plotting.
121+
122+
2. We load the Iris dataset using scikit-learn's `load_iris()` function and convert it to a Pandas DataFrame for easy manipulation.
123+
124+
3. We prepare the data for the violin plot by defining the categories (iris species) and choosing a color palette.
125+
126+
4. We create a Bokeh figure with appropriate titles and labels.
127+
128+
5. For each iris species, we:
129+
- Subset the data for that species.
130+
- Compute the kernel density estimation (KDE) using NumPy's histogram function.
131+
- Scale the KDE to create the violin shape.
132+
- Add the violin shape to the plot using Bokeh's `patch` method, creating a symmetrical violin by mirroring the shape.
133+
134+
6. We customize the plot by removing the x-axis grid, setting the y-axis range, and adding axis labels.
135+
136+
7. Finally, we display the plot using Bokeh's `show` function.
137+
138+
The resulting violin plot will show the distribution of sepal lengths for each iris species. The width of each "violin" represents the frequency of data points at that y-value, giving us a clear visualization of the data distribution. This allows us to compare not just the central tendencies of each species' sepal length, but also the spread and shape of the distributions.
139+
140+
This visualization can help us identify differences between the species. For example, we might see that one species has a broader distribution of sepal lengths, while another has a more concentrated distribution. We might also observe multimodal distributions or other interesting patterns that wouldn't be apparent from simple summary statistics.

renderings/dark-brand.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
color:
2+
background: "#282B30"
3+
foreground: "#aaaaaa"
4+
primary: white
5+
typography:
6+
fonts:
7+
- family: "Montserrat"
8+
source: google
9+
base:
10+
family: "Montserrat"
11+
monospace-block:
12+
background-color: "rgba(233, 236, 239, 0.14)"

renderings/dark-fixups.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/*-- scss:rules --*/
2+
3+
nav.sidebar.sidebar-navigation:not(.rollup) {
4+
background-color: #282B30;
5+
}

renderings/flextable.qmd

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
title: flextable
3+
execute:
4+
echo: false
5+
warning: false
6+
---
7+
8+
```{r}
9+
#| echo: false
10+
#| warning: false
11+
library(flextable)
12+
library(quarto)
13+
14+
light_theme <- theme_brand_flextable('light-brand.yml')
15+
dark_theme <- theme_brand_flextable('dark-brand.yml')
16+
```
17+
18+
```{r}
19+
#| renderings: [light, dark]
20+
21+
ft <- flextable(airquality[ sample.int(10),])
22+
ft <- add_header_row(ft,
23+
colwidths = c(4, 2),
24+
values = c("Air quality", "Time")
25+
)
26+
ft <- theme_vanilla(ft)
27+
ft <- add_footer_lines(ft, "Daily air quality measurements in New York, May to September 1973.")
28+
ft <- color(ft, part = "footer", color = "#666666")
29+
ft <- set_caption(ft, caption = "New York Air Quality Measurements")
30+
31+
ft |> light_theme()
32+
ft |> dark_theme()
33+
```
34+
35+
Here's a [link](https://example.com).
36+
37+
{{< lipsum 2 >}}

renderings/ggiraph.qmd

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: ggiraph
3+
---
4+
5+
```{r}
6+
#| echo: false
7+
#| warning: false
8+
library(quarto)
9+
library(ggplot2)
10+
library(ggiraph)
11+
12+
light_theme <- theme_brand_ggplot("light-brand.yml")
13+
dark_theme <- theme_brand_ggplot("dark-brand.yml")
14+
```
15+
16+
```{r}
17+
#| renderings: [light, dark]
18+
cars <- ggplot(mtcars, aes(mpg, wt)) +
19+
geom_point_interactive(aes(colour = factor(cyl), tooltip = rownames(mtcars))) +
20+
scale_colour_manual(values = c("darkorange", "purple", "cyan4"))
21+
22+
girafe(ggobj = cars + light_theme)
23+
girafe(ggobj = cars + dark_theme)
24+
```

0 commit comments

Comments
 (0)