Plot XKCD Graphs

Plot XKCD Graphs

XKCD is a popular figure web comic with themes in mathematics, science, language, and romance created by Randall Munroe. The xkcd package provides a simple method to plot xkcd graphs. The tweet is my learning notes for xkcd: Plotting XKCD graphs.

Install xkcd package from CRAN

R
1
install.packages("xkcd",dependencies = TRUE)

Additionally, you need to install xkcd font manually: xkcd.ttf.

A Basic Example

R
1
2
3
4
5
ggplot(mtcars) +
geom_point(aes(x = mpg, y = wt)) +
labs(title = "A Basic example") +
theme_ipsum(base_family = "xkcd",
grid = "")

Axis, Stick Figures and Facets

R
1
2
3
4
5
6
7
8
xrange <- range(mtcars$mpg)
yrange <- range(mtcars$wt)
ggplot(mtcars) +
geom_point(aes(x = mpg, y = wt,
color = as.character(vs))) +
labs(title = "A Basic example", color = "vs") +
theme_ipsum(base_family = "xkcd") +
xkcdaxis(xrange, yrange)

R
1
2
3
4
5
6
7
8
9
10
11
12
13
volunteers <- data.frame(
year = c(2007:2011),
number = c(56470, 56998, 59686, 61783, 64251)
)
xrange <- range(volunteers$year)
yrange <- range(volunteers$number)

ggplot(volunteers) +
geom_smooth(aes(x = year, y = number), method = "loess") +
xkcdaxis(xrange, yrange) +
ylab("Volunteers at Caritas Spain") +
theme_ipsum(base_family = "xkcd",
grid = "")

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data <- volunteers
data$xmin <- data$year - 0.1
data$xmax <- data$year + 0.1
data$ymin <- 50000
data$ymax <- data$number
xrange <- range(min(data$xmin)-0.1, max(data$xmax) + 0.1)
yrange <- range(min(data$ymin) + 500, max(data$ymax) + 1000)
mapping <- aes(xmin=xmin,ymin=ymin,xmax=xmax,ymax=ymax)
ggplot() +
xkcdrect(mapping, data) +
xkcdaxis(xrange, yrange) +
xlab("Year") +
ylab("Volunteers at Caritas Spain") +
theme_ipsum(base_family = "xkcd",
grid = "")

This package doesn’t look very easy to use.

chart.xkcd

chart.xkcd is a Javascript chart library that plots “sketchy”, “cartoony” or “hand-drawn” styled charts.

I tried to pack this chart library into a R package, but I failed.

Fortunely, This chart library is very easy to use:

Line Chart:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<svg class="line-chart"></svg>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.xkcd.min.js"></script>
<script>
const svg = document.querySelector('.line-chart')

new chartXkcd.Line(svg, {
title: 'Monthly income of an indie developer',
xLabel: 'Month',
yLabel: '$ Dollars',
data: {
labels:['1', '2', '3', '4', '5', '6','7', '8', '9', '10'],
datasets: [{
label: 'Plan',
data: [30, 70, 200, 300, 500 ,800, 1500, 2900, 5000, 8000],
}, {
label: 'Reality',
data: [0, 1, 30, 70, 80, 100, 50, 80, 40, 150],
}]
},
options: {}
});
</script>

XY Chart:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<svg class="xy-chart"></svg>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.xkcd.min.js"></script>
<script>
const svg2 = document.querySelector('.xy-chart');

new chartXkcd.XY(svg2, {
title: 'Pokemon farms', //optional
xLabel: 'Coodinate', //optional
yLabel: 'Count', //optional
data: {
datasets: [{
label: 'Pikachu',
data: [{ x: 3, y: 10 }, { x: 4, y: 122 }, { x: 10, y: 100 }, { x: 1, y: 2 }, { x: 2, y: 4 }],
}, {
label: 'Squirtle',
data: [{ x: 3, y: 122 }, { x: 4, y: 212 }, { x: -3, y: 100 }, { x: 1, y: 1 }, { x: 1.5, y: 12 }],
}],
},
options: { //optional
xTickCount: 5,
yTickCount: 5,
legendPosition: chartXkcd.config.positionType.upRight,
showLine: false,
timeFormat: undefined,
dotSize: 1,
},
});
</script>

Bar Chart:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<svg class="bar-chart"></svg>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.xkcd.min.js"></script>
<script>
const svg3 = document.querySelector('.bar-chart')

const barChart = new chartXkcd.Bar(svg3, {
title: 'github stars VS patron number', // optional
// xLabel: '', // optional
// yLabel: '', // optional
data: {
labels: ['China', 'Japan', 'America', 'England', 'Russia'],
datasets: [{
data: [100, 20, 90, 2, 30],
}],
},
options: { // optional
yTickCount: 5,
dataColors: ["#2C3E50", "#E31A1C", "#18BC9C", "#CCBE93", "#A6CEE3"]
},
});

</script>

Pie/Doughnut Chart:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<svg class="pie-chart"></svg>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.xkcd.min.js"></script>
<script>
const svg4 = document.querySelector('.pie-chart');
const pieChart = new chartXkcd.Pie(svg4, {
title: 'What Tim made of', // optional
data: {
labels: ['a', 'b', 'e', 'f', 'g'],
datasets: [{
data: [500, 200, 80, 90, 100],
}],
},
options: { // optional
innerRadius: 0.5,
legendPosition: chartXkcd.config.positionType.upRight,
},
});
</script>

Radar Chart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<svg class="radar-chart"></svg>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.xkcd.min.js"></script>
<script>
const svg5 = document.querySelector('.radar-chart');

const radarChart = new chartXkcd.Radar(svg5, {
title: 'Letters in random words',
data: {
labels: ['c', 'h', 'a', 'r', 't'],
datasets: [{
label: 'ccharrrt',
data: [2, 1, 1, 3, 1],
}, {
label: 'chhaart',
data: [1, 2, 2, 1, 1],
}],
},
options: {
showLegend: true,
dotSize: 0.8,
showLabels: true,
legendPosition: chartXkcd.config.positionType.upRight,
// unxkcdify: true,
},
});
</script>

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×