Link axes in Makie.jl if other plot elements present - plot

I would like to create multiple subplots with their own individual legends and shared y-axis limits. I am currently creating the subplots in a loop by doing the following:
fig = Figure()
for i in 1:3
lines(fig[i, 1], rand(10), label="$i")
end
linkyaxes!(fig.content...)
fig
This works fine, but when attempting to add a legend to each subplot next:
fig = Figure()
for i in 1:3
lines(fig[i, 1], rand(10), label="$i")
axislegend()
end
linkyaxes!(fig.content...)
fig
this now throws an error:
MethodError: Cannot `convert` an object of type Makie.MakieLayout.Legend to an object of type Makie.MakieLayout.Axis
because fig.content now includes Makie.MakieLayout.Legend() objects, in addition to the original Axis objects from before.
Do I need to filter these out beforehand, or is there a better way to produce the desired plots?

I'm not sure this is the best approach, but you could ensure that you pass the axes to linkyaxes! this way:
axs = []
fig = Figure()
for i in 1:3
ax = lines(fig[i, 1], rand(10), label="$i").axis
push!(axs, ax)
axislegend()
end
linkyaxes!(axs...)

Related

R: 1 Dimensional "scatterplot"

I am using the R programing language. Recently, I came across this previous stackoverflow post where it describes how to make a 1 dimensional scatter plot in R: How can I plot a 1-D plot in R?:
x <- rnorm(100,10,10)
x <- data.frame(x,1) ## 1 is your "height"
plot(x, type = 'o', pch = '|', ylab = '')
My question: is it possible to transform the above plot into a "plotly" plot?
Suppose I have the following data:
library(plotly)
x <- rnorm(100,10,10)
color <- rnorm(100, 2,1)
frame = data.frame(x,color)
Would it be possible to do something like this?
fig <- plot_ly(data = frame, x = ~frame$x, color ~ frame$color )
fig
I get the following error when running this code:
No trace type specified:
Based on info supplied, a 'histogram' trace seems appropriate.
Can someone please show me how to do this?
Thanks
Source: https://plotly.com/r/line-and-scatter/
In plotly language, a trace is the type of visualization that you would like to use to display your data. So the error basically lets you know that you have not specified any trace and that the program is picking one for you: "a histogram". For scatterplots, you need type = "scatter" and mode = "markers'.
Also, inside the plot_ly() function, once you specify the data argument, you can simply access the columns with the column name preceded by a tilde ~.
Finally, since you want a one dimensional scatterplot along the x-axis, you need to add y = " " to the plot_ly() function.
This is how you can achieve your desired result:
library(plotly)
x <- rnorm(100,10,10)
color <- rnorm(100, 2,1)
frame = data.frame(x,color)
plot_ly(type = "scatter", mode = "markers", data = frame, x = ~x, y = " ", color = ~color )
Note that plotly is a very rich framework and you can read the appropriate documentation to learn how to customize your plot to your liking.

What exactly is the z argument in plot_ly?

I have three variables: x,y, and z and I want to produce a surface plot.
z<-runif(50,0,1)
y<-runif(50,1,2)
x<-runif(50,3,6)
plot_ly(x = ~x, y = ~y, z= ~z) %>% add_surface()
I get the following error
Error: `z` must be a numeric matrix
What exactly does z represent if not the variable corresponding to the vertical axis? I have seen the Volcano example where they use the matrix to generate that plot, but I still am not sure what that z matrix represents in that example either.
What I would like is for someone to plot an easy to understand 3D function like z=f(x,y) = x^2 + y^2 using the surface functionality in plot_ly just so I can understand how to generate a plot based on three variables.
The problem with your above code is, that you haven't specified the trace type - and what you need to pass to the z argument depends on this specification.
Passing the arguments x, y, z suggests you want to display a scatter3d plot - you can test this by dropping add_surface():
z <- runif(50,0,1)
y <- runif(50,1,2)
x <- runif(50,3,6)
plot_ly(x = x, y = y, z = z)
Which gives the warning:
No trace type specified: Based on info supplied, a 'scatter3d' trace
seems appropriate. Read more about this trace type ->
https://plot.ly/r/reference/#scatter3d No scatter3d mode specifed:
Setting the mode to markers Read more about this attribute ->
https://plot.ly/r/reference/#scatter-mode
add_surface() on the other hand suggests you want to display a 3D Surface Plot.
You already mentioned the volcano example. This kind of plot only needs a single numeric matrix to create the plot (argument z).
Accordingly with your example code you mixed up both plot types which leads to the error message.
How to avoid this confusion?
If you have a look at ?plot_ly there is a description for arguments "..." passed to the according trace type (z is one of them):
Arguments (i.e., attributes) passed along to the trace type. See
schema() for a list of acceptable attributes for a given trace type
(by going to traces -> type -> attributes).
schema() is a very useful hint to orient oneself in the plotly library. Execute the following code to browse through the different plotly trace types and their available attributes in a very convenient way:
# install.packages("listviewer")
library(plotly)
library(listviewer)
schema(jsonedit = interactive())
I guess this is what you were after in the first place:
z <- runif(50,0,1)
y <- runif(50,1,2)
x <- runif(50,3,6)
plot_ly(x = x, y = y, z = z, type = 'mesh3d')

Categorical axes in plotly heatmapgl

Hi I've some problems with heatmapgl plot (but with heatmap I get the same) of plotly package.
I've a distance matrix between a series of elements. I would like to plot a heatmap with names of elements on axes and possibly also on hover text labels.
library(plotly)
values=c(22.63409, 323.93780, 366.31498, 467.94524, 461.93251, 643.61306, 665.03471, 482.49047, 500.06208, 662.71600, 673.29995, 567.99427, 558.41419, 632.86704, 615.55000, 508.01659, 462.50232, 411.39160, 399.00598, 286.55681, 268.69871)
z_matrix=matrix(NA,7,7)
z_matrix[lower.tri(z_matrix, diag=FALSE)] <- values
elements_names=c("ATHOTPlun04", "ATHOTPlun10", "ATHOTPlun16", "ATHOTPlun22", "ATHOTPmar04", "ATHOTPmar10", "ATHOTPmar16")
q <- plot_ly(
x=elements_names,
y=elements_names,
z = z_matrix, type = "heatmapgl") %>%
layout(title = 'Distances for ATHOTP route')
q
Although this is what I get when I run the code:
I tried also to set axes type to "category" in layout options but nothing seems to change. What am I missing? Thank you!
heatmap-gl is used for images where you have continuous x- and y-axes. Therefore you need to change type to a non-continuous type, e.g. type = "heatmap".
q <- plot_ly( x=elements_names,
y=elements_names,
z = z_matrix, type = "heatmap") %>%
layout(title = 'Distances for ATHOTP route')
q

Programmatically getting the labels in Octave

In Octave, when I plot I can get the plot object. For example
pl = get(plot(...))
I can then specify the labels such as:
xlabel("something")
I'm working on an auto-grader and need to check the contents of the xlabel from the plot object pl. I'd think I'd be able to say something like
disp(all(pl.xlabel == "something"))
But, I'm getting an error saying xlabel doesn't belong to the plot object.
If there is only one axis object, you could get the current axis object with gca, then get the labels and such through the axis object.
ax = gca
disp(get(get(ax, "XLabel") "String"))
If you have multiple plots on different figures and no handle to the figure, you could do the following where you get the figure, rather than directly use gca:
p1 = plot((1:10).^2);
p2 = plot((1:10).^4);
xlabel('Matt');
fig = ancestor(p1, 'figure');
ax = get(fig, "CurrentAxes");
disp(get(get(ax, "XLabel") "String"))

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