2014-03-27 1 views
1

하나의 선 그래프 아래에 그룹화 된 막대를 어떻게 그릴 수 있습니까?동일한 차트에서 R-ggplot을 사용하여 막대와 두 개의 Y 축에 한 줄을 그리는 방법은 무엇입니까?

그림은 분류 실험 (예 : 정확도)의 실적을 선 (두껍고 표준)으로 표시 할 수 있습니다. 왼쪽 Y- 스케일을 사용하여 0 < Accuracy < 1 사이의 변이와 "This is accuracy"텍스트를 사용하십시오.

그런 다음 (예 : 텍스트 분류의) 피쳐 수를 막대로 표시 할 수 있습니다. 오른쪽 Y- 축, 0 < NOoFeatures < max(featuresX) 사이의 변형, 텍스트 : "기능 수". 엑스 스케일, 텍스트 "각 실험에 사용 된 기능".

실제로는 스택 형 (좋을 것) 또는 그룹화 (선호하는) 표시가 가능한 텍스트 기능의 네 가지 범주가 있습니다.)

## Mock-up data: 
performanceExps <- c(0.4, 0.5, 0.65, 0.9) # Accuracy 
FeaturesExp1 <- c(featuresA=1000, featuresB=0, featuresC=0, featuresD=0) # Used features Experiment 1 
FeaturesExp2 <- c(featuresA=1000, featuresB=5000, featuresC=0, featuresD=0) # Used features Experiment 2 
FeaturesExp3 <- c(featuresA=1000, featuresB=5000, featuresC=10000, featuresD=0) # Used features Experiment 3 
FeaturesExp4 <- c(featuresA=1000, featuresB=5000, featuresC=10000, featuresD=20000) # Used features Experiment 4 

Kohske 이벤트 (아래) 꽤 비슷하지만, 나는 내 문제 (사용 바)에 적응 할 수없는 하나의 예; 이제 모든 그레이 스케일 톤에 표시되는 경우, 완벽 할 것입니다.

library(ggplot2) 
library(gtable) 
library(grid) 

grid.newpage() 

# two plots 
p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_line(colour = "blue") + theme_bw() 
p2 <- ggplot(mtcars, aes(mpg, drat)) + geom_line(colour = "red") + theme_bw() %+replace% 
    theme(panel.background = element_rect(fill = NA)) 

# extract gtable 
g1 <- ggplot_gtable(ggplot_build(p1)) 
g2 <- ggplot_gtable(ggplot_build(p2)) 

# overlap the panel of 2nd plot on that of 1st plot 
pp <- c(subset(g1$layout, name == "panel", se = t:r)) 
g <- gtable_add_grob(g1, g2$grobs[[which(g2$layout$name == "panel")]], pp$t, 
        pp$l, pp$b, pp$l) 

# axis tweaks 
ia <- which(g2$layout$name == "axis-l") 
ga <- g2$grobs[[ia]] 
ax <- ga$children[[2]] 
ax$widths <- rev(ax$widths) 
ax$grobs <- rev(ax$grobs) 
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm") 
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1) 
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b) 

grid.draw(g) 

여기에 질문이 종료 -이 hrbmstr의 코드

featPerf <- data.frame(expS=c("1", "2", "3", "4"), 
         Experiment1=c(1000, 0, 0, 0), 
         Experiment2=c(1000, 5000, 0, 0), 
         Experiment3=c(1000, 5000, 10000, 0), 
         Experiment4=c(1000, 5000, 10000,20000), 
         accuracy=c(0.4, 0.5, 0.65, 0.9)) 

# make room for both axes ; adjust as necessary 
par(mar=c(5, 12, 6, 7) + 0.4) 

# plot the bars first with no annotations and specify limits for y 
#barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", ylim=c(0, max(colSums(featPerf[2:5])))) 
barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", beside=TRUE) 

# make the bounding box (or not...it might not make sense for your plot) 
#box() 

# now make the left axis 
axis(2, ylim=c(0, max(colSums(featPerf[2:5]))), col="black", las=1) 

# start a new plot 
par(new=TRUE) 

# plot the line; adjust lwd as necessary 
plot(x=1:4, y=featPerf[,6], xlab="Experiments", ylab="", axes=FALSE, type="l", ylim=c(0,1), lwd=5) 

# annotate the second axis 
axis(4, ylim=c(0,1), col="black", col.axis="black", las=1) 
#axis(4, ylim=c(0,1), col="black", col.axis="black", las=1, labels="Accuracy", at = .5, side=3) 

#title("An Example of Creative Axes", xlab="X values", ylab="Y=X") 
mtext("Accuracy", side=4, line=3, cex.lab=1,las=2, col="black") 
mtext("No. of features ", side=2, line=3, cex.lab=1,las=2, col="black") 
+0

귀하의 데이터는 무엇입니까? 원하는 RPM 샘플을 붙여 넣기 외에 어떤 방법으로 시도 했습니까? – hrbrmstr

+0

@hrbrmstr 감사합니다 :) 위의 설명에 실물 크기의 데이터를 추가했습니다. – alex

답변

4

Kohske의 예를 수정하여 해결. 이것은 hrbrmstr의 솔루션과 비슷한 플롯의 결과입니다. 플롯을 재고하는 데 완전히 동의합니다.

library(ggplot2) 
library(gtable) 
library(reshape2) 

# Data 
featPerf <- data.frame(exp=c("1", "2", "3", "4"), 
        A=c(1000, 1000, 1000, 1000), 
        B=c(0, 5000, 5000, 5000), 
        C=c(1000, 5000, 10000, 0), 
        D=c(1000, 5000, 10000 ,20000), 
        accuracy=c(0.4, 0.5, 0.65, 0.9)) 

# Barplot ------------------------------------------------ 
# Reshape data for barplot 
df.m <- melt(featPerf[-6]) 

# Labels for barplot 
df.m$barlab <- factor(paste("Experiment", df.m$exp)) 

p1 <- ggplot(df.m , aes(x=barlab, y=value, fill=variable)) + 
      geom_bar(stat="identity", position="dodge") + 
      scale_fill_grey(start =.1, end = .7) + 
      xlab("Experiments") + 
      ylab("Number of Labels") + 
      theme(legend.position="top") 
g1 <- ggplotGrob(p1) 

# Lineplot ------------------------------------------------ 
p2 <- ggplot(featPerf , aes(x=exp, y=accuracy, group=1)) + geom_line(size=2) + 
      scale_y_continuous(limits=c(0,1)) + 
      ylab("Accuracy") + 
      theme(panel.background = element_rect(fill = NA), 
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank()) 
g2 <- ggplotGrob(p2) 


# Add plots together 
pp <- c(subset(g1$layout, name == "panel", se = t:r)) 
g <- gtable_add_grob(g1, g2$grobs[[which(g2$layout$name == "panel")]], pp$t, 
       pp$l, pp$b, pp$l) 


# Add second axis for accuracy 
ia <- which(g2$layout$name == "axis-l") 
ga <- g2$grobs[[ia]] 
ax <- ga$children[[2]] 
ax$widths <- rev(ax$widths) 
ax$grobs <- rev(ax$grobs) 
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm") 
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1) 
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b) 


# Add second y-axis title 
ia <- which(g2$layout$name == "ylab") 
ax <- g2$grobs[[ia]] 
# str(ax) # you can change features (size, colour etc for these - 
# change rotation below 
ax$rot <- 270 
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1) 
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b) 

grid.draw(g) 
+0

그것은 작동합니다 :) 대단한! 고맙습니다. 너 훌륭해. 그러나'ggplot p1' 다음에 회색 음영'+ scale_fill_grey (시작 = .1, 끝 = .7)'(작동)을 설정하고, 비늘'xLabels <- c ("Experiment1", "Experiment2", "Experiment3 ","Experiment4 ")'(작동하지 않음),'xName ="실험 "(작동하지 않음),'yLeftName ="레이블 수 ",'yRightName' ="정확도 "'(작동하지 않음). – alex

+0

플롯은 실험에서 사용 된 다른 (추가) 기능의 정확도에 대한 영향을 보여줍니다. 당신이 완벽한 아닌 ggplot (누락 된 전설을 제외하고)를보고 싶다면 내 질문 아래의 코드를 사용하십시오. 고마워요 :) – alex

+0

@alex; 업데이트 됨 - 조정할 수있는 몇 가지 사항이 있습니다. 재미 있습니다. – user20650

1

들으을 데이터 샘플을 게시 (감사합니다!)! I 생각해 보면입니다. CAVEAT : 이중 축 플롯에 관해서는 Few [PDF] 캠프에 단단히 붙어 있기 때문에 나란히 배치하는 것이 좋습니다. 이유가 있습니다.ggplot2은 어렵게 만듭니다. 이를 위해 기본 그래픽에 의지 할 의향이 있다면 매우 간단합니다.

# make a data frame for convenience 

featPerf <- data.frame(exp=c("1", "2", "3", "4"), 
         A=c(1000, 1000, 1000, 1000), 
         B=c(0, 5000, 5000, 5000), 
         C=c(1000, 5000, 10000, 0), 
         D=c(1000, 5000, 10000 ,20000), 
         accuracy=c(0.4, 0.5, 0.65, 0.9)) 

# make room for both axes ; adjust as necessary 
par(mar=c(5, 5, 5, 7) + 0.2) 

# plot the bars first with no annotations and specify limits for y 
barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", ylim=c(0, max(colSums(featPerf[2:5])))) 

# make the bounding box (or not...it might not make sense for your plot) 
box() 

# now make the left axis 
axis(2, ylim=c(0, max(colSums(featPerf[2:5]))), col="black", las=1) 

# start a new plot 
par(new=TRUE) 

# plot the line; adjust lwd as necessary 
plot(x=1:4, y=featPerf[,6], xlab="", ylab="", axes=FALSE, type="l", ylim=c(0,1), lwd=5) 

# annotate the second axis 
axis(4, ylim=c(0,1), col="black", col.axis="black", las=1) 

plot

당신은 조정하거나 주석/여백을 추가 할 수 있습니다

는/색상을 수행해야한다. 나는 충분히 피해를 입혔다 :-)

+0

감사합니다. 아주 좋습니다! 열을 그룹화 할 수 있습니까? 또한 필자는 스택 된 컬럼을 상상 한 방법을 보여주기 위해 귀하의 개작 된 코드를 제 질문에 추가했습니다. 너무 자주 나는 내가 원하는만큼 정확하지 않다 (미안하다!). pacience '에 감사드립니다. : - |' – alex

+0

안녕하세요, 감사합니다! 나는 변이를 달성했다 (위의 주석 참조). 먼저 질문 (스택, 그룹)에 답하기 위해 내 질문 아래의 코드를 확인하고 추가하십시오. 필자가 아주 새롭기 때문에, 잠깐 여유를 가질 수 있다면, ylab 텍스트로 열 스케일링의 충돌을 피하기 위해 코드를 변경하고 y- 스케일 사이에 기본 범례를 추가하면됩니다. 줄과 바 (이것은 기술적으로 가능합니다), 테두리 없음. 큰 감사를 드린다. 월요일에 내 논문을 제출하고 있는데,이 사실을 알기까지 몇 시간이 걸릴 것입니다. – alex

+0

다른 문제가 발생했습니다. 오른쪽에'labels = "Accuraces"를 추가하면 유선 오류가 발생합니다. 'labels'이 제공되고 'at'가 아닙니다. 고맙습니다. – alex

관련 문제