Wie können wir Diagramme im xkcd-Stil erstellen?

697

Anscheinend haben die Leute herausgefunden, wie man in Mathematica und in LaTeX Diagramme im xkcd- Stil erstellt . Können wir das in R machen? Ggplot2-er? Ein geom_xkcd und / oder theme_xkcd?

Ich denke in Basisgrafiken, par (xkcd = TRUE)? Wie mache ich es?

xkcd # 1064

Als ersten Stich (und wie viel eleganter unten gezeigt) in ggplot2 sorgt das Hinzufügen des Jitter-Arguments zu einer Linie für einen großartigen handgezeichneten Look. Damit -

ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) + 
  geom_line(position="jitter", color="red", size=2) + theme_bw()

Es ist ein schönes Beispiel - aber die Achsen und Schriftarten erscheinen schwieriger. Schriftarten werden jedoch gelöst angezeigt (siehe unten). Ist der einzige Weg, mit Äxten umzugehen, um sie auszublenden und von Hand einzuziehen? Gibt es eine elegantere Lösung? Kann element_line im neuen Themensystem in ggplot2 insbesondere so geändert werden, dass ein jitterartiges Argument verwendet wird?

Jebyrnes
quelle
8
Was genau würden Sie als notwendige Elemente von xkcd-Graphen betrachten? Anmerkungen? beliebige Kurven, Achsen und Skalen? handgezeichnetes Look-and-Feel?
smcg
8
Ich würde mich auf das handgezeichnete Erscheinungsbild aller Diagrammelemente konzentrieren: Achsen, Text, Linien usw.
joran
61
Vergessen Sie nicht die obligatorische Maus!
Jørgen R
4
Außerdem werden Schriftarten für xkcdsucks.blogspot.com/2009/03/…
jebyrnes
11
So sehr ich R und xkcd liebe, wer dieses Mem jemals gestartet hat, sollte sich den Kopf eintauchen lassen. Benutze einen Bleistift , Leute!
naught101

Antworten:

424

Möglicherweise möchten Sie das folgende Paket in Betracht ziehen:

Paket xkcd : Zeichnen von ggplot2-Grafiken in einem XKCD-Stil.

library(xkcd)
vignette("xkcd-intro")

Einige Beispiele (Streudiagramme, Balkendiagramme):

  • Streudiagramm:

Streudiagramm

  • Balkendiagramm:

Balkendiagramm

Emilio Torres Manzanera
quelle
@smillig, aus der Windows-R-Version ReadMe : "Binärpakete werden ca. 1-3 Tage nach Veröffentlichung der Quellen auf CRAN verfügbar sein."
GSee
43
Was muss ich zitieren, wenn ich das Paket in Veröffentlichungen verwende?
Ziggystar
1
+1 Und danke für das tolle Paket. Ich habe Probleme bei der Installation der Schriftarten ! Eine Korrektur in der Intro-Datei (Abschnitt 2.1, Zeile 5, .tff -> .ttf). Ein weiterer steht noch aus !!
Shambho
1
Großartige Arbeit, ich mag das theme_xkcd (), mit dem wir es sehr einfach verwenden können. Wenn Sie es verbessern möchten, würde ich vorschlagen, dass xkcdaxis () ohne Argument aufgerufen werden kann (es würde nur die normale Achse zeichnen). dh ggplot (data = temp.all, aes (x = State.Code, y = Sample.Value, fill = year)) + geom_boxplot () + coord_cartesian (ylim = c (0,40)) + theme_xkcd () + xkcdaxis ()
Zipp
es scheint, dass etwas darin kaputt ist. Installation installiert xkcd, aber versuchen, library(xkcd)Erträge zu erzielen > library(xkcd) Loading required package: extrafont Registering fonts with R Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : there is no package called ‘acepack’ Error: package or namespace load failed for ‘xkcd’und Erträge zu acepackerzielen> install.packages("ace") Warning in install.packages : package ‘ace’ is not available (for R version 3.2.1)
Shawn Mehan
216

In Anlehnung an einige der anderen Antworten habe ich das Diagramm "nicht gezeichnet" und auch die Flexibilität der Beschriftungspositionen auf der x-Achse (die in xkcd üblich zu sein scheint) und eine beliebige Beschriftung auf dem Diagramm hinzugefügt Diagramm.

Beachten Sie, dass ich einige Probleme beim Laden der Humor Sans-Schriftart hatte und sie manuell in das Arbeitsverzeichnis heruntergeladen habe.

Geben Sie hier die Bildbeschreibung ein

Und der Code ...

library(ggplot2)
library(extrafont)

### Already have read in fonts (see previous answer on how to do this)
loadfonts()

### Set up the trial dataset 
data <- NULL
data$x <- seq(1, 10, 0.1)
data$y1 <- sin(data$x)
data$y2 <- cos(data$x)
data$xaxis <- -1.5

data <- as.data.frame(data)

### XKCD theme
theme_xkcd <- theme(
    panel.background = element_rect(fill="white"), 
    axis.ticks = element_line(colour=NA),
    panel.grid = element_line(colour="white"),
    axis.text.y = element_text(colour=NA), 
    axis.text.x = element_text(colour="black"),
    text = element_text(size=16, family="Humor Sans")
    )

 ### Plot the chart
 p <- ggplot(data=data, aes(x=x, y=y1))+
      geom_line(aes(y=y2), position="jitter")+
      geom_line(colour="white", size=3, position="jitter")+
      geom_line(colour="red", size=1, position="jitter")+
      geom_text(family="Humor Sans", x=6, y=-1.2, label="A SIN AND COS CURVE")+
      geom_line(aes(y=xaxis), position = position_jitter(h = 0.005), colour="black")+
      scale_x_continuous(breaks=c(2, 5, 6, 9), 
      labels = c("YARD", "STEPS", "DOOR", "INSIDE"))+labs(x="", y="")+
      theme_xkcd

ggsave("xkcd_ggplot.jpg", plot=p, width=8, height=5)
Mark Bulling
quelle
Das ist fantastisch! Wenn es nur eine Möglichkeit gäbe, element_line dazu zu bringen, ein Jitter-Argument zu verwenden, um es in Themen umzuwandeln ... das würde den Deal besiegeln, denke ich.
Jebyrnes
1
Könnte es ein fehlendes Paket in Ihrem Code geben, erhalte ich "Fehler: Funktion" Thema konnte nicht gefunden werden "in theme_xkcd <- theme (
Owe Jessen
1
Hm, was ist dann die Lösung für die Fehlermeldung? - Eine neuere Version von ggplot2hat den Trick gemacht.
Rico
Ich habe festgestellt, dass die Verwendung geom_smoothmit method = "loess", span = 0.6, se = FALSEund position = position_jitter(h=0.005)bei rauschenden Daten bessere Ergebnisse liefert, da die Linien sowohl glatt als auch verwackelt sind.
Zeehio
Fehlt noch etwas? Fehler in grid.Call (C_textBounds, as.graphicsAnnot (x $ label), x $ x, x $ y ,: Polygonkante nicht gefunden Ruft auf: ggsave ... <Anonymous> -> widthDetails -> widthDetails.text -> grid .Call fordert: Warnmeldungen: 1: In grid.Call (C_textBounds, as.graphicsAnnot (x $ label), x $ x, x $ y ,: Für Familie "Humor Sans" wurde kein Zeichensatz gefunden werden ... versucht angehalten
Coliban
189

Grundlegende Strichzeichnungsfunktion:

xkcd_line <- function(x, y, color) {
  len <- length(x);
  rg <- par("usr");
  yjitter <- (rg[4] - rg[3]) / 1000;
  xjitter <- (rg[2] - rg[1]) / 1000;
  x_mod <- x + rnorm(len) * xjitter;
  y_mod <- y + rnorm(len) * yjitter;
  lines(x_mod, y_mod, col='white', lwd=10);
  lines(x_mod, y_mod, col=color, lwd=5);
}

Grundachse:

xkcd_axis <- function() {
  rg <- par("usr");
  yaxis <- 1:100 / 100 * (rg[4] - rg[3]) + rg[3];
  xaxis <- 1:100 / 100 * (rg[2] - rg[1]) + rg[1];
  xkcd_line(1:100 * 0 + rg[1] + (rg[2]-rg[1])/100, yaxis,'black')
  xkcd_line(xaxis, 1:100 * 0 + rg[3] + (rg[4]-rg[3])/100, 'black')
}

Und Beispielcode:

data <- data.frame(x=1:100)
data$one <- exp(-((data$x - 50)/10)^2)
data$two <- sin(data$x/10)
plot.new()
plot.window(
    c(min(data$x),max(data$x)),
    c(min(c(data$one,data$two)),max(c(data$one,data$two))))
xkcd_axis()
xkcd_line(data$x, data$one, 'red')
xkcd_line(data$x, data$two, 'blue')

Produziert:

Beispieldiagramm

user295691
quelle
137

Hier ist ein Versuch mit den Schriftarten, basierend auf Links aus den xkcd-Foren und dem extrafontPaket:

Wie oben erwähnt, gibt es auf der xkcd-Website eine Forumsdiskussion über Schriftarten : Ich habe die erste gefunden, die ich finden konnte. Möglicherweise gibt es andere (bessere?) Optionen (@jebyrnes veröffentlicht eine weitere Quelle für mögliche Schriftarten in den obigen Kommentaren - die TTF-Datei ist hier ; jemand hat einen 404-Fehler für diese Quelle gemeldet. Sie können es auch hier oder hier versuchen und die folgenden URLs entsprechend ersetzen. xkcdFontURLMöglicherweise müssen Sie etwas härter arbeiten, um die von Github geposteten Links abzurufen.

   xkcdFontURL <- "http://simonsoftware.se/other/xkcd.ttf"
   download.file(xkcdFontURL,dest="xkcd.ttf",mode="wb")

(Dies ist für den einmaligen Quickie-Gebrauch gedacht: Für den regulären Gebrauch sollten Sie es in einem Standard-Systemschriftverzeichnis ablegen.)

   library(extrafont)

Die nützlichsten Informationen zu Schriftarten befanden sich auf der Extrafont-Github-Site - diese wird von dort übernommen

font_import(".")   ## because we downloaded to working directory
loadfonts()

Beispiel mehr oder weniger wörtlich von der Github-Seite genommen:

library(ggplot2)
p <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() +
  ggtitle("Fuel Efficiency of 32 Cars") +
  xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
  theme(text=element_text(size=16, family="xkcd"))

ggsave("xkcd_ggplot.pdf", plot=p,  width=4, height=4)
## needed for Windows:
##   Sys.setenv(R_GSCMD = "C:/Program Files/gs/gs9.05/bin/gswin32c.exe")
embed_fonts("xkcd_ggplot.pdf")

Geben Sie hier die Bildbeschreibung ein

Ben Bolker
quelle
32

Ich habe einen Analysekalender mit xkcd-Motiven nur mit RStudio entworfen. Hier ist ein Beispiel für den xkcd-Stil eines Balkendiagramms

  • Verwendete Schriftart = HumorSans.ttf [Link oben angegeben]
  • Verwendetes Paket [xkcd]

Um dieses Diagramm zu generieren Barplot-Proxy für "Gefahren bei der Arbeit"

Hier ist der verwendete Code

#using packages xkcd, ggplot 
library(xkcd)
library(ggplot2)
font_import(pattern="[H/h]umor")
loadfonts()

### Set up the trial dataset 
d1 <- data.frame('type'=c('DROWNING','RADIATION','TOILET',"ELECTRICAL",'NOISE','PANTRY','YOUR    FALLING ON OBJECTS','OBJECTS FALLING ON YOU','BOSS','FIRE','TRAVEL TO WORK'),'score'=c(2,2,3,6,6,6,11,14,21,26,30))

# we will keep adding layers on plot p. first the bar plot
p <- NULL
p <- ggplot() + xkcdrect(aes(xmin = type-0.1,xmax= type+0.1,ymin=0,ymax =score),
                     d1,fill= "#D55E00", colour= "#D55E00")  +
     geom_text(data=d1,aes(x=type,y=score+2.5,label=score,ymax=0),family="Humor Sans") +   coord_flip()

#hand drawn axes
d1long <- NULL
d1long <- rbind(c(0,-2),d1,c(12,32))
d1long$xaxis <- -1
d1long$yaxis <- 11.75

# drawing jagged axes
p <- p + geom_line(data=d1long,aes(x=type,y=jitter(xaxis)),size=1)
p <- p + geom_line(data=d1long,aes(x=yaxis,y=score), size=1) 

# draw axis ticks and labels
p <- p +  scale_x_continuous(breaks=seq(1,11,by=1),labels = data$Type) +
     scale_y_continuous(breaks=NULL)

#writing stuff on the graph
t1 <- "GOOGLE RESULTS"
p <- p + annotate('text',family="Humor Sans", x=12.5, y=12, label=t1, size=6) 

# XKCD theme
p <- p + theme(panel.background = element_rect(fill="white"),
           panel.grid = element_line(colour="white"),axis.text.x = element_blank(), 
           axis.text.y = element_text(colour="black"),text = element_text(size=18, family="Humor   Sans") ,panel.grid.major = element_blank(),panel.grid.minor = element_blank(),panel.border = element_blank(),axis.title.y = element_blank(),axis.title.x = element_blank(),axis.ticks = element_blank())

print(p)
d2a2d
quelle
14

Dies ist ein sehr, sehr rauer Anfang und deckt nur (teilweise) das handgezeichnete Erscheinungsbild der Linien ab. Es würde ein wenig Arbeit erfordern, um dies zu automatisieren, aber das Hinzufügen von AR (1) -Rauschen zur Antwortfunktion könnte dazu führen, dass es leicht von Hand gezeichnet erscheint

set.seed(551)
x <- seq(0, 1, length.out = 1000)
y <- sin(x)

imperfect <- arima.sim(n = length(y), model = list(ar = c(.9999)))
imperfect <- scale(imperfect)
z <- y + imperfect*.005
plot(x, z, type = "l", col = "blue", lwd = 2)
Dason
quelle
13

Hier ist meine Sicht auf die ggplot2Verwendung eines Teils des Codes von oben:

ggplot()+geom_line(aes(x=seq(0,1,length.out=1000),y=sin(x)),position=position_jitter(width=0.02),lwd=1.5,col="white")+
  geom_line(aes(x=seq(0,1,length.out=1000),y=sin(x)),position=position_jitter(width=0.004),lwd=1.4,col="red")+
  geom_line(aes(x=seq(0,1,length.out=1000),y=cos(x)),position=position_jitter(width=0.02),lwd=1.5,col="white")+
  geom_line(aes(x=seq(0,1,length.out=1000),y=cos(x)),position=position_jitter(width=0.004),lwd=1.4,col="blue")+
  theme_bw()+theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank())

Ich bin mir nicht sicher, wie ich die Achsen ersetzen soll, könnte aber den gleichen Ansatz mit verwenden jitter. Dann geht es darum, die Schriftart aus XKCD zu importieren und mit zu überlagern geom_text.

jslefche
quelle