Question Comment pouvons-nous faire des graphes de style xkcd?


Apparemment, les gens ont compris comment faire xkcd graphiques de style dans Mathematica et dans LaTeX. Pouvons-nous le faire en R? Ggplot2-ers? Un geom_xkcd et / ou un theme_xkcd?

Je suppose que dans les graphiques de base, par (xkcd = TRUE)? Comment fait-on ça?

xkcd#1064

Comme un premier coup (et beaucoup plus élégamment montré ci-dessous) dans ggplot2, l'ajout de l'argument jitter à une ligne fait un grand coup d'oeil dessiné à la main. Alors -

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

C'est un bon exemple - mais les axes et les polices semblent plus délicats. Les polices apparaissent résolues (ci-dessous), cependant. Est-ce que la seule façon de traiter avec des axes pour les vider et les dessiner à la main? Y a-t-il une solution plus élégante? En particulier, dans ggplot2, element_line dans le nouveau système de thème peut-il être modifié pour prendre un argument de type jitter?


616
2017-10-01 14:22


origine


Réponses:


Vous pourriez vouloir considérer le paquet suivant:

Package xkcd: Tracer des graphiques ggplot2 dans un style XKCD.

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

Quelques exemples (Scatterplots, Bar Graphiques):

  • Scatterplot:

Scatterplot

  • Diagramme à bandes:

Bar Chart


375
2018-05-16 20:49



En pensant à la même ligne que les autres réponses, j'ai "décallé" le graphique et ajouté la flexibilité des emplacements des étiquettes de l'axe des x (qui semble être commun dans xkcd) et une étiquette arbitraire sur le graphique.

Notez que j'ai eu quelques problèmes avec le chargement de la police Humor Sans et l'ai téléchargé manuellement dans le répertoire de travail.

enter image description here

Et le 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)

201
2017-10-01 22:11



Fonction de dessin au trait basique:

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

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

Et un exemple de code:

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

Produit:

Example chart


182
2017-10-01 20:47



Voici une tentative pour les polices, basée sur les liens des forums xkcd et le extrafont paquet:

Comme indiqué ci-dessus, il y a un discussion du forum sur les polices sur le site xkcd: J'ai attrapé le premier que je pourrais trouver, il peut y avoir d'autres (mieux?) Options (@jebyrnes publie une autre source pour les polices possibles dans les commentaires ci-dessus - le fichier TTF est ici; quelqu'un a signalé une erreur 404 pour cette source, vous pouvez également essayer ici ou ici, en remplaçant ces URL de manière appropriée xkcdFontURL au dessous de; vous devrez peut-être travailler un peu plus fort pour récupérer les liens postés par Github)

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

(Ceci est pour une utilisation rapide et unique: pour un usage régulier, vous devriez le mettre dans un répertoire de polices système standard.)

   library(extrafont)

Les informations les plus utiles sur les polices étaient sur le site github extrafont - Ceci est pris à partir de là

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

Exemple pris plus ou moins textuellement du site 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")

enter image description here


128
2017-10-01 20:09



J'ai conçu un calendrier d'analyse sur le thème xkcd en utilisant simplement RStudio. Voici un exemple de style de tracé de barres xkcd

  • Police utilisée = HumorSans.ttf [lien donné ci-dessus]
  • Paquet utilisé [xkcd]

Pour générer ce complot Bar plot proxy for 'Dangers at Work'

Voici le code utilisé

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

27
2017-12-24 07:24



C'est un début très, très approximatif et ne couvre que (partiellement) l'aspect dessiné à la main des lignes. Il faudrait un peu de travail pour automatiser cela, mais ajouter du bruit AR (1) à la fonction de réponse pourrait faire paraître légèrement dessinés à la main

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)

14
2017-10-01 14:41



Voici ma prise sur les lignes avec ggplot2en utilisant une partie du code ci-dessus:

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

Je ne sais pas comment remplacer les axes, mais pourrait utiliser la même approche avec jitter. Ensuite, il s'agit d'importer la police de XKCD et de superposer geom_text.


13
2017-10-01 20:01