2013-09-17 2 views
6

Обычно я использую ggplot2, но в этом случае я использую обычную функцию image() для построения тепловой карты большого набора данных. Я могу маркировать всех этикеток как красные, но я хочу, чтобы обозначить ось ординат с текстом различных цветов на основе вектора цветовых определений, которые я произвожу:Различные цвета осевых меток в R на основе другой переменной

grid = structure(c(1:12),.Dim = c(4,3)) 
labs = c("A","B","C") 
image(1:4,1:3,grid,axes=FALSE, xlab="", ylab = "") 
#This works but isn't the colors I want 
axis(2,at=1:length(labs),labels=labs,las=2, adj=1,cex.axis=0.6,col.axis="red") 

Это создает следующее изображение:

Example plot

Я хотел бы метки а и с, чтобы быть черным и B, чтобы быть красным. Это то, что я пытался, но он дает ошибку «Неверная длина» ...

axiscolors = c("black","red","black") 
axis(2,at=1:length(labs),labels=labs,las=2, adj=1, cex.axis=0.6, col.axis=axiscolors) 

Это эффект после того, как я с некоторыми «реальных» данных ...

actual heatmap

EDIT:

В качестве резервной копии, если это возможно в ggplot2, я, возможно, захочу изменить коэффициент кода. Есть еще несколько приложений, которые я бы использовал для этого.

Я придумал, как построить слой красных символов над верхними старыми этикетками, но предпочел бы нативный метод с вектором цвета, если это возможно ...

sublabs = c("B") 
axis(2,at=match(sublabs,labs),labels=sublabs,las=2, adj=1, cex.axis=0.6, col.axis="red") 

Другим способом будет использовать text(), если я мог бы поставить метки вне сюжетного пространства ...

text(c(1,1,1),c(1,2,3),labs,col=c("black","red","black")) 

UPDATE: ниже решение, которое работает с ggplot2 ...

+0

Не думаю, что вы найдете «собственный метод». Между авторами R существует довольно сильное культурное сопротивление в отношении того, что некоторые люди называют «харчевкой». –

+1

Интересно. Я умный Tufte-an, но «харк-диаграмма» одного человека - это информация другого человека. (В примере, отличном от игрушки, у меня есть 91 значение по оси y, и я помечен 16 вновь перемешанными строками, чтобы выделить, где они выходят.) – beroe

+0

Я действительно смотрел код, который подвергается постоянному пользователю и ничего не видел который может быть взломан в чистом R для 'graphics :: axis'. Интересно, может ли grid-графика предоставить проспект. Я вижу, что существует решетчатая версия 'lattice :: axis.default', и похоже, что раздел« do.labels »будет многообещающим. Возможно, вам также понадобится взломать 'решетка :: panel.axis'. –

ответ

6

Если вы проигнорируете такие векторизованные возможности, как text и mtext, вы можете попасть туда, повторно звонив axis. Временные затраты на обслуживание будут минимальными, и это позволит провести все вычисления axis, как обычно. Например:

# original code 
grid = structure(c(1:12),.Dim = c(4,3)) 
labs = c("A","B","C") 
image(1:4,1:3,grid,axes=FALSE, xlab="", ylab = "") 
axiscolors = c("black","red","black") 

# new code  
Map(function(x,y,z) 
    axis(2,at=x,col.axis=y,labels=z,lwd=0,las=1), 
    1:3, 
    axiscolors, 
    labs 
) 
axis(2,at=1:3,labels=FALSE) 

Результирующее в:

enter image description here

+0

Спасибо. Мне нравится это решение, поскольку оно, похоже, хорошо масштабируется и использует естественную команду 'axis()' вместо того, чтобы настраивать позицию 'text'. – beroe

3

Принимая ответ @ thelatemail как наиболее гибкий, но он также оказывается довольно просто с помощью text() если вы добавите xpd = TRUE чтобы черчения вне Рамка. Использование mtext() также может работать, но оно не позволяет вам rotate labels.

grid = structure(c(1:20),.Dim = c(4,5)) 
labs = c("A","B","C","D","E") 
redlabs = c("B","D") 
colorlist = c("black","red") 
# one of many ways to generate the color labels 
axiscolor = colorlist[labs %in% redlabs +1 ] 

image(1:4,1:5,grid,axes=FALSE, xlab="", ylab = "") 
axis(2,at=1:length(labs),labels=FALSE) 

# This would work for sideways labels 
# mtext(text=labs, side=2,at=1:length(labs),col=axiscolor,adj=.5) 
text(labels=labs, col=axiscolor, x=rep(.45,length(labs)), y=1:length(labs), srt = 0, pos = 2, xpd = TRUE) 

Solution using text()

UPDATE для ggplot2: Вы можете использовать theme() и element_text, чтобы установить цвета и другие параметры. Что-то вроде этого...

p + theme(axis.text.y = element_text(color=axiscolor)) 
1

Вы можете указать вектор с цветами, которые вы хотите применить к меткам, а затем использовать цикл, чтобы получить этикетки цветные с осью(). В следующем примере я использую другой цвет для каждого уровня точечной диаграммы.

DF <- data.frame(habitat=c("Hab 1","Hab 2","Hab 3","Hab 4","Hab 5"), mean=c(0.53,0.28,0.30,0.35,0.39), color=colors()[c(24,257,26,504,652)]) 
> DF 
habitat mean  color 
1 Hab 1 0.53  black 
2 Hab 2 0.28  green3 
3 Hab 3 0.30  blue 
4 Hab 4 0.35 orangered1 
5 Hab 5 0.39  yellow 

par(mar=c(7, 5, 4, 3)) 
dotchart(DF[,2], xlim=c(0.2,0.6), col=as.character(DF$color), pch=16, lcolor="white", xlab=colnames(DF[2])) # Plot the points 
for (j in 1:5){ 
axis(side=2, at=j, col.axis=as.character(DF$color)[j], labels=DF$habitat[j], las=1) # Add habitat as labels, each with corresponding color, on the left margin 
} 
+0

Это может сработать. Я просто хочу, чтобы был способ сделать это как вектор вместо цикла: 'axis (side = 2, at = as.numeric (среда обитания DF $), col.axis = as.character (цвет DF $), метки = DF $ habitat, las = 1) ' – beroe

0

Мне нравится подход очень thelatemail, и может добавить только небольшое уточнение, так как фиксированный «на» позиции (как в приведенном выше примере с at = 1:3) не работает хорошо для меня. В моем случае мне нужно было создать барплот и предоставить собственные значения для параметров пространства и ширины. В конце я использовал (например, случайные данные, в которых я хотел, чтобы бары и метки для положительных (неотрицательных, если точнее) значений данных были зелеными и красными. В этом примере я также использую letters функцию для нанесения меток и поворота меток с помощью las = 2):

x <- rnorm(26) 
color <- rep("green", length(x)) 
color[x < 0] <- "red" 

par(mar=c(6,4.1,4.1,2.1)) 
barplot(x, las = 2, ylim = c(min(x)-0.5, max(x)+0.5), col = color, space = 0.5, width = 2)  
Map(function(x,y,z) 
axis(1,at=x,col.axis=y,labels=z,lwd=0,las=2), 
seq(from = 2, by = 3, length.out = length(x)), 
color, 
letters 
) 
axis(1,at=seq(from = 2, by = 3, length.out = length(x)),labels=FALSE) 
Смежные вопросы