Plotting values on a regular 2D grid in Julia - julia

There is a certain parameter values set over a regular 2D lattice. I want to display them in the form of cells of a regular grid, filled in with a color depending of the value of the parameter. There may be gaps in individual grid nodes. Here is an example of the data and the desired result of plotting:
a = [1, 2, 3, 1, 2, 3, 1, 2]
b = [1, 1, 1, 2, 2, 2, 3, 3]
c = [1, 5, 4, 3, 4, 2, 1, 3]
plot(a, b, zcolor = c, aspect_ratio = 1, xlim = (0.5, 3.5), ylim = (0.5, 3.5), clim = (0, 5),
seriestype = :scatter, markersize = 82, markershape = :square, markerstrokewidth = 0.5,
legend = false, colorbar = true)
This approach works, but in this case, is needed to adjust the size of the squares each time so that there are no gaps between the cells and they do not run over each other. This requires constant manual intervention and does not look like the right solution. What is the most correct approach in this case? I thought about heatmap(), but as far as I understand, in Julia it does not know how to display cell borders. Perhaps there is some way to set in plot() the icon sizes in absolute canvas units? Or is it better to use some other approach for such situations?

heatmap seems like the way to go to me. If your a and b spanned the entire lattice, I would just use reshape to, well, reshape c. This is not your case here, so one solution is to fill the lattice with NaNs where you have no value. E.g.,
using Plots
a = [1, 2, 3, 1, 2, 3, 1, 2]
b = [1, 1, 1, 2, 2, 2, 3, 3]
c = [1, 5, 4, 3, 4, 2, 1, 3]
x, y = sort(unique(a)), sort(unique(b)) # the lattice x and y
C = fill(NaN, length(y), length(x)) # make a 2D C with NaNs
for (i,j,v) in zip(a,b,c) # fill C with c values
C[j,i] = v
end
heatmap(x, y, C, clims=(0,5)) # success!
gives
EDIT: If you want to specify the edges of the cells, you can do this with heatmap, and if you want lines, you can add them manually I guess, for example with vline and hline?
ex, ey = [0, 1.5, 2.3, 4], [0.5, 1.5, 2.5, 3.5]
heatmap(ex, ey, C, clims=(0,5))
vline!(ex, c=:black)
hline!(ey, c=:black)
will give

Related

Is there a way in R to customize the height proportion of graphs without using the heights statement within layout?

Here is the code I'm starting with.
par(mar = c(2, 2, 2, 1),
mgp = c(1.1, 0.15, 0),
tck = -0.01)
a <- rnorm(500)
layout(mat = matrix(c(2, 2,
1, 3), 2, byrow = TRUE),
widths = c(2, 1),
heights = c(3, 2))
plot(a)
hist(a)
boxplot(a)
I was wondering if there is a way to change the graph proportions without using widths and heights. I figured out that I could do mat = matrix(c(2,2,2,1,1,3) to change the column ratio, but I'm not sure about the heights. Any help is appreciated!

Using R's layout when columns have a different number of rows

I wish to create a plot in R that has 11 panels: three in a left-hand column, and eight in a right-hand column. I'd like the three left-hand plots to be the same height, and the eight right-hand plots to be the same height.
I can get some way using layout and hacking the margins: but because it's not possible to specify negative margins, this doesn't allow me to use the full space in the left column. Moreover, margins may look different if the plot is later sent to a PDF device with a different page size.
layout(matrix(c(1, 1, 0, 2, 2, 0, 3, 3, 3 + (1:8)), ncol=2),
widths=c(0.33, 0.67))
par(mar=c(0, 2, 2, 2))
plot(c(1, 1))
par(mar=c(0, 2, 0, 2))
plot(c(1, 1))
par(mar=c(2, 2, 0, 2))
plot(c(1, 1))
par(mar=rep(2, 4))
for (i in 1:8) plot(c(2, 2), col='red')
Is there a way to do this such that the three left-hand plots are equally sized and spaced, and use all the available space?
(edit:) MichaelChirico has pointed out that I could use 8×3 rows, which is viable for this example, but becomes cumbersome when there are multiple columns with different numbers of rows; I believe that layout can only support up to 200 rows.
Here's an example using your code and split.screen. Obviously you'll want to adjust the margins.
dev.off()
split.screen(figs = c(1, 2))
split.screen(figs = c(3, 1), screen = 1)
screen(n = 3)
par(mar=c(0, 2, 2, 2))
plot(c(1, 1))
screen(n = 4)
par(mar=c(0, 2, 2, 2))
plot(c(1, 1))
screen(n = 5)
par(mar=c(0, 2, 2, 2))
plot(c(1, 1))
split.screen(figs = c(8, 1), screen = 2)
for (i in 6:13) {
screen(n = i)
plot(c(2, 2), col='red')
}

How to have multiple lines and different font sizes in names.arg of a barplot in R?

I'm trying to create a barplot where each bar has an x-axis label "Name [linebreak] N=123", where the second line with "N=123" is displayed in a smaller font.
Consider this example:
t <- table(
factor(c(1, 1, 1, 1, 1, 1, 2, 1, 2, 2)),
factor(c(1, 1, 3, 2, 2, 2, 2, 2, 3, 1))
)
counts <- colSums(t) # 3, 5, 2
colnames(t) <- c("A", "B", "C")
barplot(t)
The figure looks like this (cropped):
I'd like to add the counts for each level A, B, C from the variable counts to the labels (in a smaller font), so that it looks something like this:
Is there any way to achieve that in R?
barplot returns "the coordinates of all the bar midpoints" (from ?barplot), which you can use to add text to the plot.
b <- barplot(t)
mtext(paste("N = ", counts), side=1, line=2, at=b)
# Use `mtext` to easily write to plot margins
# side=1 : bottom
# line=2 : counts out the way - so (I think) one is at the axis labels, so one more
# at: use the positions calculated by barplot

How to make the length of y axis longer in histogram in R

I have used the following code to generate the histogram. However, I want to make the y axis longer since it is too short, may I know how to do it?
> h<-hist(data, breaks=c(0,1, 2, 3, 4), col="grey",xlim = c(0,4), xlab="",xaxt="n",main="")
> axis(side=1, at=0.5:3.5, labels=c(1,2,3,4))
You could use ylim parameter to hist:
hist(mtcars$mpg, ylim=c(0,15))
c(0,15) gives the range to y axis.
A graph will fill whole available area (i.e. window). You could limit that by using layout.
layout(matrix(c(1, 0, 0, 1, 0, 0, 1, 2, 3), 3, 3, byrow = TRUE))
hist(mtcars$mpg, ylim=c(0,15))

How to rescale label on x axis in log2(n+1) format?

I want to format my x-axis in log2(n+1) format so the x-axis labels correspond to 1, 2, 4, 16 and so on.
Input:
x <- c(1, 2, 3, 11, 15)
y <- c(1.1, 1.2, .4, 2.1, 1.5)
plot(log2(x + 1), y, axes=FALSE)
axis(1, at=(labels=as.character(formatC(x))), cex.axis=0.9)
But plot I get still has the original x-axis values.
How can I make my x-axis powers of 2 (1, 2, 4, 16, etc.)?
I guess this is what you want.
x<-c(1,2,3,11,15)
y<-c(1.1,1.2,.4,2.1,1.5)
lab<-c(1,2,4,16)
plot(log2(x+1),y,xaxt="n",xlab="x")
axis(1,at=log2(lab+1),labels=lab)
It might also be useful to calculate equally spaced labels:
lab<-round(2^seq(min(log2(x+1)),max(log2(x+1)),length.out=4)-1)

Resources