Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R package Kohonen - how to plot hexagons instead of circles as in Matlab SOM toolbox?

Tags:

plot

r

som

Is it possible to plot the SOM map (package Kohonen) with hexagons as elementary forms instead of circles? Now the different plottings (count, changes etc.) are plotted as circles with white surroundings.

The aim is to create SOM visuals similar to Matlab SOM Toolbox.

This discussion suggests hexagon plotting would not have been possible 2010.

like image 817
user2968765 Avatar asked Nov 08 '13 12:11

user2968765


3 Answers

Even though there is already an answer, perhaps this different method will be a good addition. With the code you can create a heatmap similar to the one below

Resulting SOM Heatmap for my Dummy SOM

I took this piece of code from a more extensive program I wrote around the kohonen package. You can find my full explanation of the program here: http://nbremer.blogspot.nl/2013/07/on-creation-of-extended-self-organizing.html

It is a bit coding and you need to start with a specific kind of variable: the input <<Heatmap matrix variable>> is a matrix that would be the numerical representation of you heatmap. Here [1,1] will become the lower left node (1st row, 1st column), [1,2] will become the node to the right, [2,1] will be the first node to the left in the second row, etc. So visually you work your way from bottom left to top right in the Heatmap, while in the matrix you work from top left to bottom right

library(RColorBrewer) #to use brewer.pal
library(fields) #to use designer.colors

#Function to create the polygon for each hexagon
Hexagon <- function (x, y, unitcell = 1, col = col) {
  polygon(c(x, x, x + unitcell/2, x + unitcell, x + unitcell, 
            x + unitcell/2), c(y + unitcell * 0.125, y + unitcell * 
                               0.875, y + unitcell * 1.125, y + unitcell * 0.875, 
                               y + unitcell * 0.125, y - unitcell * 0.125), 
          col = col, border=NA)
}#function

#Start with a matrix that would be the numerical representation of you heatmap
#Here [1,1] will become the lower left node (1st row, 1st column), 
#[1,2] will become the node to the right
#[2,1] will be the first node to the left in the second row
#So visually you work your way from bottom left to top right
x <- as.vector(<<Heatmap matrix variable>>)

#Number of rows and columns of your SOM
SOM_Rows <- dim(<<Heatmap matrix variable>>)[1]
SOM_Columns <- dim(<<Heatmap matrix variable>>)[2]

#To make room for the legend
par(mar = c(0.4, 2, 2, 7))

#Initiate the plot window but do show any axes or points on the plot
plot(0, 0, type = "n", axes = FALSE, xlim=c(0, SOM_Columns), 
     ylim=c(0, SOM_Rows), xlab="", ylab= "", asp=1)

#Create the color palette 
#I use designer.colors to interpolate 50 colors between 
#the maxmimum number of allowed values in Brewer 
ColRamp <- rev(designer.colors(n=50, col=brewer.pal(9, "Spectral")))

#Make a vector with length(ColRamp) number of bins between the minimum and 
#maximum value of x. 
#Next match each point from x with one of the colors in ColorRamp
ColorCode <- rep("#FFFFFF", length(x)) #default is all white
Bins <- seq(min(x, na.rm=T), max(x, na.rm=T), length=length(ColRamp))
for (i in 1:length(x))
    if (!is.na(x[i])) ColorCode[i] <- ColRamp[which.min(abs(Bins-x[i]))] 

#Actual plotting of hexagonal polygons on map
offset <- 0.5 #offset for the hexagons when moving up a row
for (row in 1:SOM_Rows) {
  for (column in 0:(SOM_Columns - 1)) 
     Hexagon(column + offset, row - 1, col = ColorCode[row + SOM_Rows * column])
  offset <- ifelse(offset, 0, 0.5)
}

#Add legend to the right if you want to
image.plot(legend.only=TRUE, col=ColRamp, zlim=c(min(x, na.rm=T), max(x, na.rm=T)))
like image 195
nadieh Avatar answered Nov 18 '22 20:11

nadieh


I don't have sufficient reputation to comment on @NBremer's answer. I have extended the above code to allow visualization of large component planes and u-matrices for output from the R "kohonen" library. Code and worked examples available here:

R SOM Visualization Functions

Detail of Output

like image 28
GeoSS Avatar answered Nov 18 '22 22:11

GeoSS


You can use Voronoi plots to get a space filled representation (hexagons).

  • the hex grid coordinates are stored in $grid$pts of the kohonen object,
  • the codes are in $codes

Putting this together with a lattice plot:

require ("kohonen")
require ("latticeExtra")
require ("deldir")
som.wines <- som (scale (wines), grid = somgrid(5, 5, "hexagonal"))

df <- as.data.frame (cbind (som.wines$grid$pts, som.wines$codes))
levelplot (alcohol ~ x * y, data = df, panel = panel.voronoi, aspect = "iso)

yields:

kononen map hex plot

(I don't know for sure, but I guess that would have been possible already in 2010).

like image 22
cbeleites unhappy with SX Avatar answered Nov 18 '22 20:11

cbeleites unhappy with SX