Combining title across mfrow in R - r

I would like the title to be centered above the two plots in my mfrow object. Indeed, I have just that working, but the title is too far above the plots, and is only half included because of this. Below is my code showing the issue. How can I move the title down to just above the plots in the center?
a=1
p = c(rnorm(1000,5,10))
l = c(rnorm(1000,10,5))
par(mfrow=c(1,2))
hist(p,main=NULL)
hist(l,main=NULL)
title(main=print(paste0("Histogram a=", a)),outer=T)

If you set the line parameter in the title call to, for example, -2, you can place the title closer to the histograms:
a=1
p = c(rnorm(1000,5,10))
l = c(rnorm(1000,10,5))
par(mfrow=c(1,2))
hist(p,main=NULL)
hist(l,main=NULL)
title(main=print(paste0("Histogram a=", a)),outer=T, line=-2)

Related

Move title of plots in a list of plots in R

I have a list of plots that I have assigned names to, and then converted to plot titles as suggested by https://stackoverflow.com/a/14790376/9335733. The titles happen to appear over the top x-axis title and so I attempt to move them as suggested here: https://stackoverflow.com/a/44618277/9335733. The overall code looks as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
main = x,
adj = 0, #adjust title to the farthest left
line =2.5 #adjust title up 2.5
)
)
It should be noted that plot is now converted from base R to the oce package for analyzing oceanographic data, but calls the same arguments from base R plot.
The problem becomes that in trying to move the title, the axis labels move as well and overlap. Any suggestions?
Edit: Here is what the image looks like before:
And after:
You might also want to look into the oma= argument in par(), which provides an "outer" margin which can be used to put a nice title. Something like:
library(oce)
data(ctd)
par(oma=c(0, 0, 1, 0))
plot(ctd)
title('Title', outer=TRUE)
This was solved by adding a title argument outside of the plot function as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
which = c("temperature", "salinity", "sigmaT","conductivity"),
Tlim = c(11,12),
Slim = c(29,32),
col = "red")
+ title(main = x, adj = 0.48, line = 3.5)#adding the titles at a specific location
)
This allowed for plots that looked like:
If you use the title function, rather than setting main within plot, it would allow you to change the line without affecting anything else in the plot.

R: Remove top axis title base plot

I want to remove or rename the "top axis title" of the following plot based on the package plotmo. Here is a short reproducible example:
library(glmnet)
library(plotmo)
data(mtcars)
fit <- glmnet(x=as.matrix(mtcars[,-1]), y=as.matrix(mtcars[,1]))
plot_glmnet(fit)
Results in:
It looks like, that the plot is made by base plot functions. May someone knows a way to Change the top axis title or remove it
The only way I could achieve what you desire is by editing the source code.
plot_glmet.edited<- plot_glmnet ## copy the function
as.list(body(plot_glmet.edited)) ## print the lines of the function
At the moment the code will not print a label, replace NA with any character string that you want as a title
body(plot_glmet.edited)[[33]] <- substitute(
mtext(NA, side = 3, line = 1.5, cex = par("cex") * par("cex.lab")))

Increase space between subplots in Plots.jl

How can I increase the space between subplots in Plots.jl?
Minimal non-working example:
julia> using Plots; pyplot()
Plots.PyPlotBackend()
julia> data = [rand(100), rand(100)];
histogram(data, layout=2, title=["Dataset A" "Dataset B"], legend=false)
ylabel!("ylabel")
If you make the figure small enough, the y label of the second plot collides with the first plot.
In the attributes part of Plots.jl documentation, there is a section called Subplot. There, you will find the keywords margin, top_margin, bottom_margin, left_margin and right_margin that might help you.
Minimal working example would be, then:
using Plots, Measures
pyplot()
data = [rand(100), rand(100)];
histogram(data, layout = 2,
title = ["Dataset A" "Dataset B"], legend = false,
ylabel = "ylabel", margin = 5mm)
Note the using Measures part, by the way. I hope this helps.
Another workaround would be using the bottom_margin keyword argument holding the pyplot backend like this:
using Plots
pyplot()
x1 = rand(1:30, 20);
x2 = rand(1:30, 20);
# subplot 1
p1 = plot(
x1,
label="x1 value",
title="x1 line plot",
ylabel="x1",
bottom_margin=50*Plots.mm,
);
# subplot 2
p2 = plot(
x2,
label="x2 value",
title="x2 line plot",
xlabel="sample",
ylabel="x2",
);
plot(
p1,
p2,
layout=grid(
2,1,
)
)
An alternative is to use the empty figure object _ to occupy the space. It works well when a long legend name overlaps with another subplot with PGFPlotsX backend,
pgfplotsx()
p1 = plot(1:10, label = "a long label name")
p2 = plot(1:10)
plot(p1, p2)
we can use _ in #layout to leave more space for the legend of the first subplot,
plot(p1, p2, layout=#layout([a{0.5w} _ b{0.3w}]))
It can even handle more complicated cases. For example, you might just want to increase the space between two specific subplots instead of all subplots. For example, I use the setting
layout = #layout([grid(2, 1){0.3w} _ grid(2, 1){0.3w} b{0.33w}])
to leave more space via _ for the legend for the left two subplots grid(2,1), but do not touch other subplots.

Adding global title to Plots.jl subplots

I would like to add a global title to a group of subplots using Plots.jl.
Ideally, I'd do something like:
using Plots
pyplot()
plot(rand(10,2), plot_title="Main title", title=["A" "B"], layout=2)
but, as per the Plots.jl documentation, the plot_title attribute is not yet implemented:
Title for the whole plot (not the subplots) (Note: Not currently implemented)
In the meanwhile, is there any way around it?
I'm currently using the pyplot backend, but I'm not especially tied to it.
This is a bit of a hack, but should be agnostic to the backend. Basically create a new plot where the only contents are the title you want, and then add it on top using layout. Here is an example using the GR backend:
# create a transparent scatter plot with an 'annotation' that will become title
y = ones(3)
title = Plots.scatter(y, marker=0,markeralpha=0, annotations=(2, y[2], Plots.text("This is title")),axis=false, grid=false, leg=false,size=(200,100))
# combine the 'title' plot with your real plots
Plots.plot(
title,
Plots.plot(rand(100,4), layout = 4),
layout=grid(2,1,heights=[0.1,0.9])
)
Produces:
More recent versions of Plots.jl support the plot_title attribute, which provides a title for the whole plot. This can be combined with individual titles of individual plots.
using Plots
layout = #layout [a{0.66w} b{0.33w}]
LHS = heatmap(rand(100, 100), title="Title for just the heatmap")
RHS = plot(1:100, 1:100, title="Only the line")
plot(LHS, RHS, plot_title="Overall title of the plot")
Alternatively, you can set the title for an existing plot directly.
p = plot(LHS, RHS)
p[:plot_title] = "Overall title of the plot"
plot(p)
When using the pyplot backend, you can use PyPlot commands to alter a Plots figure, cf. Accessing backend specific functionality with Julia Plots.
To set a title for the whole figure, you could do something like:
using Plots
p1 = plot(sin, title = "sin")
p2 = plot(cos, title = "cos")
p = plot(p1, p2, top_margin=1cm)
import PyPlot
PyPlot.suptitle("Trigonometric functions")
PyPlot.savefig("suptile_test.png")
One needs to explicitly call PyPlot.savefig to see the effect of the PyPlot functions.
Note that all changes made using the PyPlot interface will be overwritten when you use a Plots function.
subplots are fields of the Plot type, and each subplot has a field called :attr that you can modify and re-display() the plot. Try the following:
julia> l = #layout([a{0.1h} ;b [c; d e]])
Plots.GridLayout(2,1)
julia> p = plot(randn(100,5),layout=l,t=[:line :histogram :scatter :steppre :bar],leg=false,ticks=nothing,border=false)
julia> p.subplots
5-element Array{Plots.Subplot,1}:
Subplot{1}
Subplot{2}
Subplot{3}
Subplot{4}
Subplot{5}
julia> fieldnames(p.subplots[1])
8-element Array{Symbol,1}:
:parent
:series_list
:minpad
:bbox
:plotarea
:attr
:o
:plt
julia> for i in 1:length(p.subplots)
p.subplots[i].attr[:title] = "subtitle $i"
end
julia> display(p)
You should now see a title in each subplot

R contour levels don't match filled.contour

Hopefully a straightforward question but I made a simple figure in R using filled.contour(). It looks fine, and what it should like given the data. However, I want to add a reference line along a contour for 0 (level = 0), and the plotted line doesn't match the colors on the filled.contour figure. The line is close, but not matching with the figure (and eventually crossing over another contour from the filled.contour plot). Any ideas why this is happening?
aa <- c(0.05843150, 0.11300040, 0.15280030, 0.183524400, 0.20772430, 0.228121000)
bb <- c(0.01561055, 0.06520635, 0.10196237, 0.130127650, 0.15314544, 0.172292410)
cc <- c(-0.02166599, 0.02306650, 0.05619421, 0.082193680, 0.10334837, 0.121156780)
dd <- c(-0.05356592, -0.01432910, 0.01546647, 0.039156660, 0.05858709, 0.074953650)
ee <- c(-0.08071987, -0.04654243, -0.02011676, 0.000977798, 0.01855881, 0.033651089)
ff <- c(-0.10343798, -0.07416114, -0.05111547, -0.032481132, -0.01683215, -0.003636035)
gg <- c(-0.12237798, -0.09753544, -0.07785126, -0.061607548, -0.04788856, -0.036169540)
hh <-rbind(aa,bb,cc,dd,ee,ff,gg)
z <- as.matrix(hh)
y <- seq(0.5,1.75,0.25)
x <- seq(1,2.5,0.25)
filled.contour(x,y,z,
key.title = title(main=expression("log"(lambda))),
color.palette = topo.colors) #This works
contour(x,y,z, level=0,add=T,lwd=3) #This line doesn't match plot
This is completely answered in the ?filled.contour help page. In the Notes section it states
The output produced by filled.contour is actually a combination of two plots; one is the filled contour and one is the legend. Two separate coordinate systems are set up for these two plots, but they are only used internally – once the function has returned these coordinate systems are lost. If you want to annotate the main contour plot, for example to add points, you can specify graphics commands in the plot.axes argument. See the examples.
And the examples given in that help page show how to annotate on top of the main plot. In this particular case, the correct way would be
filled.contour(x,y,z,
key.title = title(main=expression("log"(lambda))),
color.palette = topo.colors,
plot.axes = {
axis(1)
axis(2)
contour(x,y,z, level=0,add=T,lwd=3)
}
)
which produces

Resources