it-swarm.com.de

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

Offensichtlich haben die Leute herausgefunden, wie man xkcd -Diagramme erstellt in Mathematica und in LaTeX . Können wir es in R tun? Ggplot2-er? Ein geom_xkcd und/oder theme_xkcd?

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

xkcd#1064

Als ersten Stich (und umso eleganter, wie 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()

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

668
jebyrnes

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

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

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

Einige Beispiele (Streudiagramme, Balkendiagramme):

  • Streudiagramm:

Scatterplot

  • Balkendiagramm:

Bar Chart

In Anlehnung an einige der anderen Antworten habe ich das Diagramm "nicht geplottet" und außerdem die Flexibilität der x-Achsen-Beschriftungspositionen (die bei xkcd üblich zu sein scheint) und eine beliebige Beschriftung auf der hinzugefügt Diagramm.

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

enter image description here

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)
212
Mark Bulling

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:

Example chart

187
user295691

Hier ist ein Versuch der Schriftarten, basierend auf Links aus den xkcd-Foren und dem extrafont -Paket:

Wie oben erwähnt, gibt es eine Forumsdiskussion über Schriftarten auf der xkcd-Site : Ich habe die erste gefunden, die ich finden konnte. Möglicherweise gibt es andere (bessere?) Optionen Kommentare oben - Die TTF-Datei ist hier ; jemand hat einen 404-Fehler für diese Quelle gemeldet. Alternativ können Sie hier oder hier versuchen und diese ersetzen URLs passend für xkcdFontURL unten; Sie müssen möglicherweise 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 nur für den einmaligen Gebrauch gedacht. Für den normalen Gebrauch sollten Sie es in ein Standardverzeichnis für Systemschriftarten legen.)

   library(extrafont)

Die nützlichsten Informationen zu Schriftarten waren auf der extrafont github-Site - diese stammen von dort

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

Beispiel mehr oder weniger wörtlich aus der Github-Site entnommen:

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

136
Ben Bolker

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

  • Font used = HumorSans.ttf [Link oben angegeben]
  • Paket verwendet [xkcd]

Um diese Handlung zu erzeugen Bar plot proxy for 'Dangers at Work'

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)
32
d2a2d

Dies ist ein sehr, sehr rauer Anfang und deckt nur (teilweise) das handgezeichnete Erscheinungsbild der Linien ab. Dies zu automatisieren, würde ein wenig Arbeit kosten, aber durch Hinzufügen von AR (1) -Rauschen zur Antwortfunktion könnte es leicht handgezeichnet erscheinen

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
Dason

Hier ist meine Einstellung zu den Zeilen mit ggplot2 mit einem Teil des obigen Codes:

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 austauschen soll, könnte aber dieselbe Vorgehensweise mit jitter verwenden. Dann müssen Sie die Schrift von XKCD importieren und mit geom_text.

13
jslefche