Bagaimana kita bisa membuat grafik gaya xkcd?

697

Rupanya, rakyat telah menemukan cara membuat grafik gaya xkcd di Mathematica dan di LaTeX . Bisakah kita melakukannya di R? Ggplot2-ers? A geom_xkcd dan / atau theme_xkcd?

Saya kira dalam grafis dasar, par (xkcd = BENAR)? Bagaimana saya melakukannya?

xkcd # 1064

Sebagai tikaman pertama (dan jauh lebih elegan ditampilkan di bawah) di ggplot2, menambahkan argumen jitter ke garis membuat tampilan tangan yang bagus. Jadi -

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

Ini menjadi contoh yang bagus - tetapi sumbu dan font tampak lebih rumit. Font muncul terpecahkan (di bawah). Apakah satu-satunya cara untuk menangani kapak untuk mengosongkannya dan menariknya dengan tangan? Apakah ada solusi yang lebih elegan? Secara khusus, di ggplot2, dapat element_line dalam sistem tema baru dimodifikasi untuk mengambil argumen seperti jitter?

jebyrnes
sumber
8
apa sebenarnya yang Anda anggap sebagai elemen yang diperlukan dari grafik xkcd? penjelasan? kurva, kapak, dan timbangan yang berubah-ubah? tampilan dan nuansa yang digambar tangan?
smcg
8
Saya akan fokus pada tampilan dan nuansa yang digambar tangan, dari semua elemen grafik: sumbu, teks, garis, dll.
joran
61
Jangan lupakan mouse wajibnya!
Jørgen R
4
Juga, font diurus xkcdsucks.blogspot.com/2009/03/...
jebyrnes
11
Sama seperti saya suka R dan xkcd, yang pernah memulai meme ini harus memiliki kepala mereka dunk Gunakan pensil , semuanya!
naught101

Jawaban:

424

Anda mungkin ingin mempertimbangkan paket berikut:

Paket xkcd : Merencanakan grafik ggplot2 dalam gaya XKCD.

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

Beberapa contoh (Scatterplots, Bar Charts):

  • Scatterplot:

Scatterplot

  • Grafik batang:

Grafik batang

Emilio Torres Manzanera
sumber
@smillig, dari windows r-release ReadMe : "Paket biner akan tersedia di CRAN sekitar 1-3 hari setelah sumber diterbitkan."
GSee
43
Apa yang harus saya kutip ketika menggunakan paket dalam publikasi?
ziggystar
1
+1 Dan terima kasih atas paketnya. Saya mengalami masalah dalam menginstal font ! Satu koreksi dalam file intro, (sec-2.1, line 5, .tff -> .ttf). Satu lagi masih tertunda !!
Shambho
1
Kerja bagus, saya sangat suka theme_xkcd () yang memungkinkan kami untuk menggunakannya dengan sangat mudah. Jika Anda ingin memperbaikinya, saya akan menyarankan agar xkcdaxis () dapat dipanggil tanpa argumen (itu hanya akan menggambar sumbu normal). yaitu ggplot (data = temp.all, aes (x = State.Code, y = Sample.Value, isi = tahun)) + geom_boxplot () + coord_cartesian (ylim = c (0,40)) + theme_xkcd () + xkcdaxis ()
zipp
tampaknya ada sesuatu dalam hal ini rusak. menginstal xkcdbekerja, tetapi mencoba untuk library(xkcd)menghasilkan > 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’dan mencoba untuk acepackmenghasilkan> install.packages("ace") Warning in install.packages : package ‘ace’ is not available (for R version 3.2.1)
Shawn Mehan
216

Berpikir di sepanjang baris yang sama dengan beberapa jawaban lain, saya telah "un-ggplotted" bagan dan juga menambahkan fleksibilitas lokasi label sumbu x (yang tampaknya umum di xkcd) dan label sewenang-wenang pada grafik.

Perhatikan bahwa saya memiliki beberapa masalah dengan memuat font Humor Sans dan mengunduhnya secara manual ke direktori yang berfungsi.

masukkan deskripsi gambar di sini

Dan kodenya ...

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
sumber
Ini fantastis! Sekarang jika saja ada cara agar element_line mengambil argumen jitter untuk mengolahnya menjadi tema ... yang akan menyegel kesepakatan, saya pikir.
jebyrnes
1
Mungkinkah ada paket yang hilang dalam kode Anda, saya mendapatkan "Kesalahan: Tidak dapat menemukan fungsi" tema "di theme_xkcd <- theme (
Owe Jessen
1
Hm, lalu apa solusi untuk pesan kesalahan? - Versi yang lebih baru dari ggplot2melakukan trik.
Rico
Saya menemukan bahwa menggunakan geom_smoothdengan method = "loess", span = 0.6, se = FALSEdan position = position_jitter(h=0.005)memberi saya hasil yang lebih baik pada data yang berisik, karena garis-garisnya halus dan gugup.
zeehio
Masih ada sesuatu yang hilang? Fehler in grid.Call (C_textBounds, as.graphicsAnnot (x $ label), x $ x, x $ y,: Polygonkante nicht gefunden Ruft auf: ggsave ... <Anonim> -> widthDetails -> widthDetails.text -> grid .Call Zusätzlich: Warnmeldungen: 1: Di 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

Fungsi menggambar garis dasar:

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

Sumbu dasar:

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

Dan kode sampel:

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

Menghasilkan:

Contoh grafik

pengguna295691
sumber
137

Berikut adalah upaya font, berdasarkan tautan dari forum xkcd dan extrafontpaket:

Seperti disebutkan di atas ada diskusi forum tentang font di situs xkcd : Saya mengambil yang pertama yang bisa saya temukan, mungkin ada opsi lain (lebih baik?) (@Jebyrnes memposting sumber lain untuk kemungkinan font dalam komentar di atas - file TTF ada di sini ; seseorang melaporkan kesalahan 404 untuk sumber itu, Anda dapat mencoba alternatifnya di sini atau di sini , mengganti URL-URL itu dengan tepat di xkcdFontURLbawah; Anda mungkin harus bekerja sedikit lebih keras untuk mengambil tautan yang diposting Github)

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

(Ini untuk quickie, sekali pakai: untuk penggunaan reguler Anda harus meletakkannya di beberapa direktori font sistem standar.)

   library(extrafont)

Informasi yang paling berguna tentang font ada di situs github extrafont - ini diambil dari sana

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

Contoh yang diambil kurang lebih kata demi kata dari situs 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")

masukkan deskripsi gambar di sini

Ben Bolker
sumber
32

Saya merancang kalender analitik bertema xkcd hanya menggunakan RStudio. Berikut adalah contoh gaya plot bar xkcd

  • Font yang digunakan = HumorSans.ttf [tautan diberikan di atas]
  • Paket digunakan [xkcd]

Untuk menghasilkan plot ini Proxy plot plot untuk 'Bahaya di Tempat Kerja'

Ini kode yang digunakan

#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
sumber
14

Ini adalah awal yang sangat, sangat kasar dan hanya mencakup (sebagian) tampilan dan nuansa garis yang digambar tangan. Butuh sedikit kerja untuk mengotomatisasi ini tetapi menambahkan beberapa AR (1) noise ke fungsi respons bisa membuatnya tampak sedikit digambar tangan

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)
Alasan
sumber
13

Inilah pendapat saya tentang ggplot2beberapa kode dari atas:

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

Tidak yakin bagaimana cara mengganti kapak, tetapi bisa menggunakan pendekatan yang sama dengannya jitter. Maka itu masalah mengimpor font dari XKCD dan layering dengan geom_text.

jslefche
sumber