Làm thế nào chúng ta có thể tạo đồ thị kiểu xkcd?


697

Rõ ràng, dân gian đã tìm ra cách tạo ra các biểu đồ kiểu xkcd trong MathematicaLaTeX . Chúng ta có thể làm điều đó trong R không? Ggplot2-ers? Một geom_xkcd và / hoặc theme_xkcd?

Tôi đoán trong đồ họa cơ sở, mệnh (xkcd = TRUE)? Tôi phải làm nó như thế nào?

xkcd # 1064

Là một cú đâm đầu tiên (và càng được thể hiện thanh lịch hơn dưới đây) trong ggplot2, việc thêm đối số jitter vào một dòng sẽ tạo ra một cái nhìn tuyệt vời bằng tay. Vì thế -

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

Nó làm cho một ví dụ đẹp - nhưng các trục và phông chữ có vẻ phức tạp hơn. Phông chữ xuất hiện giải quyết (bên dưới), mặc dù. Là cách duy nhất để đối phó với các trục để làm trống chúng ra và vẽ chúng bằng tay? Có một giải pháp thanh lịch hơn? Cụ thể, trong ggplot2, Element_line trong hệ thống chủ đề mới có thể được sửa đổi để đưa ra một đối số giống như jitter không?


8
chính xác những gì bạn sẽ coi là các yếu tố cần thiết của đồ thị xkcd? chú thích? đường cong, trục và vảy tùy ý? vẽ tay và cảm nhận?
smcg

8
Tôi sẽ tập trung vào giao diện được vẽ bằng tay, trong tất cả các yếu tố biểu đồ: trục, văn bản, đường kẻ, v.v.
joran

61
Đừng quên con chuột bắt buộc!
Jørgen R

4
Ngoài ra, phông chữ được chăm sóc bởi xkcdsucks.blogspot.com/2009/03/ trên
jitherrnes

11
Nhiều như tôi yêu R và xkcd, những người đã từng bắt đầu meme này nên ngẩng cao đầu. Sử dụng một cây bút chì , mọi người!
nè 101

Câu trả lời:


424

Bạn có thể muốn xem xét các gói sau:

Gói xkcd : Vẽ đồ họa ggplot2 theo kiểu XKCD.

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

Một số ví dụ (Scatterplots, Bar Charts):

  • Phân tán:

Phân tán

  • Biểu đồ cột:

Biểu đồ cột


@smillig, từ cửa sổ phát hành lại ReadMe : "Các gói nhị phân sẽ có sẵn trên CRAN khoảng 1-3 ngày sau khi các nguồn được xuất bản."
GSee

43
Tôi phải trích dẫn gì khi sử dụng gói trong các ấn phẩm?
ziggystar

1
+1 Và cảm ơn về gói tuyệt vời. Tôi gặp sự cố với việc cài đặt các phông chữ ! Một điều chỉnh trong tệp giới thiệu, (sec-2.1, dòng 5, .tff -> .ttf). Một số khác vẫn đang chờ xử lý !!
Shambho

1
Tuyệt vời, tôi thực sự thích theme_xkcd () cho phép chúng tôi sử dụng nó rất dễ dàng. Nếu bạn muốn cải thiện nó, tôi sẽ đề nghị xkcdaxis () có thể được gọi nó mà không cần đối số (nó sẽ chỉ vẽ trục bình thường). tức là ggplot (data = temp.all, aes (x = State.Code, y = Sample.Value, fill = year)) + geom_boxplot () + tọa độ ()
zipp

có vẻ như một cái gì đó trong này bị hỏng. cài đặt xkcdcông trình, nhưng cố gắng library(xkcd)mang lại lợi nhuận > 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’và cố gắng cho acepacknăng suất> install.packages("ace") Warning in install.packages : package ‘ace’ is not available (for R version 3.2.1)
Shawn Mehan

216

Suy nghĩ cùng dòng với một số câu trả lời khác, tôi đã "bỏ qua" biểu đồ và cũng thêm vào tính linh hoạt của các vị trí nhãn trục x (dường như phổ biến trong xkcd) và nhãn tùy ý trên đồ thị.

Lưu ý rằng tôi có một vài vấn đề với việc tải phông chữ Humor Sans và tự tải nó xuống thư mục làm việc.

nhập mô tả hình ảnh ở đây

Và mã ...

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)

Cái này thật tuyệt! Bây giờ nếu chỉ có một cách để Element_line sử dụng một đối số jitter để biến nó thành chủ đề ... điều đó sẽ đóng dấu thỏa thuận, tôi nghĩ vậy.
jitherrnes

1
Có thể có một gói bị thiếu trong mã của bạn không, tôi nhận được "Lỗi: Không thể tìm thấy chức năng" chủ đề "trong theme_xkcd <- theme (
Owe Jessen

1
Hừm, giải pháp cho thông báo lỗi là gì? - Một phiên bản mới hơn của ggplot2lừa.
Rico

Tôi thấy rằng việc sử dụng geom_smoothvới method = "loess", span = 0.6, se = FALSEposition = position_jitter(h=0.005)mang lại cho tôi kết quả tốt hơn về dữ liệu nhiễu, vì các dòng đều mượt mà và bị xáo trộn.
zeehio

Vẫn còn thiếu thứ gì? Fehler in Grid.Call (C bản .Call Zusätzlich: Warnmeldungen: 1: Trong grid.Call (C_textBounds, as.graphicsAnnot (x $ nhãn), x $ x, x $ y,: Für Familie "hài hước Sans" konnte kein Zeichensatz gefunden werden ... Ausführung angehalten
Coliban

189

Chức năng vẽ đường cơ bản:

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

Trục cơ bản:

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

Và mã mẫu:

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

Sản xuất:

Biểu đồ ví dụ


137

Đây là một nỗ lực tại các phông chữ, dựa trên các liên kết từ các diễn đàn xkcd và extrafontgói:

Như đã lưu ý ở trên, có một cuộc thảo luận diễn đàn về phông chữ trên trang web xkcd : Tôi đã chọn cái đầu tiên tôi có thể tìm thấy, có thể có các tùy chọn khác (tốt hơn?) (@Jitherrnes đăng một nguồn khác cho các phông chữ có thể có trong các nhận xét ở trên - tệp TTF là ở đây ; có người báo cáo một lỗi 404 cho nguồn đó, bạn có thể thử cách khác ở đây hoặc ở đây , thay thế các URL thích hợp cho xkcdFontURLdưới đây, bạn có thể phải làm việc một chút khó khăn hơn để lấy liên kết Github-đăng)

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

(Đây là để sử dụng nhanh, sử dụng một lần: để sử dụng thường xuyên, bạn nên đặt nó trong một số thư mục phông chữ hệ thống tiêu chuẩn.)

   library(extrafont)

Thông tin hữu ích nhất về phông chữ là trên trang web Extrafont github - thông tin này được lấy từ đó

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

Ví dụ lấy nhiều hoặc ít nguyên văn từ trang 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")

nhập mô tả hình ảnh ở đây


32

Tôi đã thiết kế lịch phân tích theo chủ đề xkcd chỉ bằng RStudio. Dưới đây là một ví dụ về phong cách xkcd thanh cốt truyện

  • Phông chữ được sử dụng = HumorSans.ttf [liên kết đã cho ở trên]
  • Gói được sử dụng [xkcd]

Để tạo cốt truyện này Thanh cốt truyện ủy quyền cho 'Nguy hiểm tại nơi làm việc'

Đây là mã được sử dụng

#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

Đây là một khởi đầu rất, rất thô và chỉ bao gồm (một phần) giao diện vẽ tay và cảm nhận của các đường. Sẽ mất một chút công việc để tự động hóa việc này nhưng thêm một chút nhiễu AR (1) vào chức năng phản hồi có thể khiến nó có vẻ hơi bị vẽ tay

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

Dưới đây là nhận định của tôi về việc ggplot2sử dụng một số mã ở trên:

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

Không chắc chắn làm thế nào để thay thế các trục, nhưng có thể sử dụng cùng một cách tiếp cận với jitter. Sau đó, vấn đề nhập phông chữ từ XKCD và xếp lớp với geom_text.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.