Come possiamo creare grafici in stile xkcd?


697

Apparentemente, la gente ha capito come realizzare grafici in stile xkcd in Mathematica e in LaTeX . Possiamo farlo in R? Ggplot2-tori? Un geom_xkcd e / o theme_xkcd?

Immagino nella grafica di base, par (xkcd = TRUE)? Come lo faccio?

xkcd # 1064

Come primo colpo (e molto più elegantemente mostrato sotto) in ggplot2, l'aggiunta dell'argomento jitter a una linea crea un ottimo aspetto disegnato a mano. Così -

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

È un bell'esempio, ma gli assi e i caratteri sembrano più complicati. I caratteri sembrano risolti (sotto), comunque. È l'unico modo per gestire gli assi per eliminarli e disegnarli a mano? C'è una soluzione più elegante? In particolare, in ggplot2, element_line nel nuovo sistema di temi può essere modificato per assumere un argomento simile al jitter?


8
quali considereresti esattamente elementi necessari dei grafici xkcd? annotazioni? curve, assi e scale arbitrari? look-and-feel disegnato a mano?
smcg,

8
Mi concentrerei sull'aspetto disegnato a mano, di tutti gli elementi del grafico: assi, testo, linee, ecc.
joran

61
Non dimenticare il mouse obbligatorio!
Jørgen R,

4
Inoltre, i caratteri sono curati da xkcdsucks.blogspot.com/2009/03/…
jebyrnes,

11
Per quanto io ami R e xkcd, chi ha mai iniziato questo meme dovrebbe avere la testa inzuppata. Usa una matita , gente!
naught101

Risposte:


424

Potresti voler considerare il seguente pacchetto:

Pacchetto xkcd : stampa grafica ggplot2 in stile XKCD.

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

Alcuni esempi (grafici a dispersione, grafici a barre):

  • dispersione:

dispersione

  • Grafico a barre:

Grafico a barre


@smillig, dal file Leggimi di Windows r-release : "I pacchetti binari saranno disponibili su CRAN circa 1-3 giorni dopo la pubblicazione delle fonti".
GSee,

43
Cosa devo citare quando uso il pacchetto nelle pubblicazioni?
ziggystar,

1
+1 E grazie per l'ottimo pacchetto. Sto riscontrando problemi con l' installazione dei caratteri ! Una correzione nel file di introduzione, (sec-2.1, linea 5, .tff -> .ttf). Un altro ancora in sospeso !!
Shambho,

1
Ottimo lavoro, mi piace molto il theme_xkcd () che ci consente di usarlo molto facilmente. Se vuoi migliorarlo, suggerirei che xkcdaxis () possa essere chiamato senza argomento (disegnerebbe semplicemente l'asse normale). cioè 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

sembra che qualcosa in questo sia rotto. l'installazione di xkcdopere, ma cercando di library(xkcd)rendimenti > 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’e cercando per acepacki rendimenti> install.packages("ace") Warning in install.packages : package ‘ace’ is not available (for R version 3.2.1)
Shawn Mehan

216

Pensando sulla stessa linea di alcune delle altre risposte, ho "cancellato il grafico" del grafico e ho anche aggiunto la flessibilità delle posizioni dell'etichetta dell'asse x (che sembra essere comune in xkcd) e un'etichetta arbitraria sul grafico.

Si noti che ho avuto alcuni problemi con il caricamento del font Humor Sans e scaricato manualmente nella directory di lavoro.

inserisci qui la descrizione dell'immagine

E il codice ...

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)

È fantastico! Ora, se solo ci fosse un modo per fare in modo che element_line prenda un argomento jitter per elaborarlo su temi ... questo sigillerebbe l'affare, penso.
jebyrnes,

1
Potrebbe esserci un pacchetto mancante nel tuo codice, ottengo "Errore: Impossibile trovare la funzione" tema "in theme_xkcd <- tema (
Owe Jessen

1
Allora, qual è la soluzione al messaggio di errore? - Una versione più recente di ha ggplot2fatto il trucco.
Rico,

Ho scoperto che usare geom_smoothcon method = "loess", span = 0.6, se = FALSEe position = position_jitter(h=0.005)mi stava dando risultati migliori su dati rumorosi, poiché le linee sono sia lisce che instabili.
zeehio,

C'è ancora qualcosa che manca? Fehler in grid.Call (C_textBounds, as.graphicsAnnot (x $ label), x $ x, x $ y,: Polygonkante nicht gefunden Ruft auf: ggsave ... <Anonimo> -> widthDetails -> widthDetails.text -> grid .Call Zusätzlich: Warnmeldungen: 1: In grid.Call (C_textBounds, as.graphicsAnnot (x $ label), x $ x, x $ y,: Für Familie "Humor Sans" konnte kein Zeichensatz gefunden werden ... Ausführung angehalten
Coliban,

189

Funzione di base del disegno a tratteggio:

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);
}

Asse di base:

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')
}

E codice di esempio:

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')

produce:

Esempio grafico


137

Ecco un tentativo di font, basato sui collegamenti dai forum di xkcd e dal extrafontpacchetto:

Come notato sopra c'è una discussione nel forum sui caratteri sul sito xkcd : ho preso il primo che ho trovato, potrebbero esserci altre opzioni (migliori?) (@Jebyrnes pubblica un'altra fonte per possibili caratteri nei commenti sopra - il file TTF è qui ; qualcuno ha segnalato un errore 404 per quella fonte, in alternativa potresti provare qui o qui , sostituendo gli URL in modo appropriato con quelli di xkcdFontURLseguito; potresti dover lavorare un po 'di più per recuperare i link pubblicati da Github)

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

(Questo è per un rapido utilizzo una tantum: per un uso regolare dovresti inserirlo in una directory di font di sistema standard.)

   library(extrafont)

Le informazioni più utili sui font sono state sul sito extrafont github - questo è preso da lì

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

Esempio preso più o meno alla lettera dal sito github:

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")

inserisci qui la descrizione dell'immagine


32

Ho progettato un calendario di analisi a tema xkcd usando solo RStudio. Ecco un esempio di stile xkcd del grafico a barre

  • Carattere utilizzato = HumorSans.ttf [link fornito sopra]
  • Pacchetto utilizzato [xkcd]

Per generare questa trama Proxy del diagramma a barre per "Dangers at Work"

Ecco il codice utilizzato

#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)

14

Questo è un inizio molto, molto approssimativo e copre solo (parzialmente) l'aspetto disegnato a mano delle linee. Ci vorrebbe un po 'di lavoro per automatizzare questo, ma l'aggiunta di un po' di rumore AR (1) alla funzione di risposta potrebbe far sembrare un po 'disegnato a mano

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)

13

Ecco la mia opinione sulle linee con l' ggplot2utilizzo del codice dall'alto:

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())

Non sono sicuro di come sostituire gli assi, ma potrebbero usare lo stesso approccio con jitter. Quindi si tratta di importare il font da XKCD e di stratificarlo geom_text.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.