PlotlyJS fails to produce a plot in Julia - julia

I came across with an odd situation that I can't understand. Running Julia 1.7.3 under Ubuntu 22.04. I have one file.jl that contains the code below. The code in area1() produces a plot. But the code in bizarre() does not. I have tried this from xTerm and under VSC. In both cases area1() plots OK but bizarre() does not.
This is driving me crazy. Any help/suggestion greatly appreciated. Thank you
using DataFrames
using Statistics
using LinearAlgebra
using PlotlyJS
function area1()
trace1 = scatter(;x=1:4, y=[0, 2, 3, 5], fill="tozeroy")
trace2 = scatter(;x=1:4, y=[3, 5, 1, 7], fill="tonexty")
plot([trace1, trace2])
end
function bizarre()
println("Start Bizarre")
trace1 = scatter(;x=1:4, y=[0, 2, 3, 5], fill="tozeroy")
trace2 = scatter(;x=1:4, y=[3, 5, 1, 7], fill="tonexty")
plot([trace1, trace2])
println("End of Bizarre")
end

The confusion stems from the fact that plot is not a plotting function. plot is a Plot-creation function i.e. it creates a Plot object with the data and characteristics you specify. It does not by itself create a figure on the screen. That is the job of the display function.
When you call area1 from the REPL in xTerm (and whatever equivalent is used in VSCode), the REPL automatically calls display on the return value of the function. This is true for any function call, and is the "print" part of "read-eval-print-loop". And functions in Julia automatically return the value of the last expression they evaluate. So, in area1, since the plot call is on the last line, the resulting Plot object is returned, and then automatically displayed by the REPL.
In bizarre, the last statement is a println, which returns nothing, so nothing is printed or displayed. The statement before that, the plot call, just creates a Plot object, but doesn't display it, so it's just created and thrown away. If you replace that line with display(plot([trace1, trace2])), you'll see that that function produces a plot too.

Related

Plot not showing in Julia

I have a file named mycode.jl with following code taken from here.
using MultivariateStats, RDatasets, Plots
# load iris dataset
println("loading iris dataset:")
iris = dataset("datasets", "iris")
println(iris)
println("loaded; splitting dataset: ")
# split half to training set
Xtr = Matrix(iris[1:2:end,1:4])'
Xtr_labels = Vector(iris[1:2:end,5])
# split other half to testing set
Xte = Matrix(iris[2:2:end,1:4])'
Xte_labels = Vector(iris[2:2:end,5])
print("split; Performing PCA: ")
# Suppose Xtr and Xte are training and testing data matrix, with each observation in a column. We train a PCA model, allowing up to 3 dimensions:
M = fit(PCA, Xtr; maxoutdim=3)
println(M)
# Then, apply PCA model to the testing set
Yte = predict(M, Xte)
println(Yte)
# And, reconstruct testing observations (approximately) to the original space
Xr = reconstruct(M, Yte)
println(Xr)
# Now, we group results by testing set labels for color coding and visualize first 3 principal components in 3D plot
println("Plotting fn:")
setosa = Yte[:,Xte_labels.=="setosa"]
versicolor = Yte[:,Xte_labels.=="versicolor"]
virginica = Yte[:,Xte_labels.=="virginica"]
p = scatter(setosa[1,:],setosa[2,:],setosa[3,:],marker=:circle,linewidth=0)
scatter!(versicolor[1,:],versicolor[2,:],versicolor[3,:],marker=:circle,linewidth=0)
scatter!(virginica[1,:],virginica[2,:],virginica[3,:],marker=:circle,linewidth=0)
plot!(p,xlabel="PC1",ylabel="PC2",zlabel="PC3")
println("Reached end of program.")
I run above code with command on Linux terminal: julia mycode.jl
The code runs all right and reaches the end but the plot does not appear.
Where is the problem and how can it be solved.
As the Output section of the Plots docs says:
A Plot is only displayed when returned (a semicolon will suppress the return), or if explicitly displayed with display(plt), gui(), or by adding show = true to your plot command.
You can have MATLAB-like interactive behavior by setting the default value: default(show = true)
The first part about "when returned" is about when you call plot from the REPL (or Jupyter, etc.), and doesn't apply here.
Here, you can use one of the other options:
calling display(p) after the last plot! call (this is the most common way to do it)
calling gui() after the last plot!
adding a show = true argument to the last plot! call
setting the default to always show the plot by setting Plots.default(show = true) at the beginning of the script
Any one of these is sufficient to make the plot window appear.
The plot closes when the Julia process ends, if that's happening too soon, you can either:
Run your code as julia -i mycode.jl at the terminal - this will run your code, display the plot, and then land you at the Julia REPL. This will both keep the plot open, and let you work with the variables in your code further if you need to.
add a readline() call at the end of your program. This will keep Julia waiting for an extra press of newline/Enter/Return key, and the plot will remain in display until you press that.
(Credit to ffevotte on Julia Discourse for these suggestions.)

Creating animated plots in the command line with Julia

Julia has the delightful ability to generate plots constructed from Unicode symbols which are printed directly to the command line in a very straightforward way. For example, the following code generates a Unicode plot of a sine function directly to the command line:
using Plots
unicodeplots();
x = [0:0.1:2*pi;];
y = sin.(x);
plot(x,y)
I would like to try to find a way to create an animated plot of this form directly on the command line. Ideally, I would like to generate a single plot in Unicode that is ``updated" in such a way that it appears animated.
However, although printing hundreds of distinct frames to the command line is naturally less appealing, such a solution is acceptable if it ``looks" like an animation. Another less acceptable solution is to print such Unicode plots into a gif in a way that is consistent for all platforms; attempts to do any of this involving jury-rigging #animate and #gif have largely failed, since either function cannot even print Unicode plots to a file in the Windows form of Julia.
UPDATE: Here is an example of code that generates an "animation" in the command line that is not really acceptable, which simply plots each distinct frame followed by "spacing" in the command line provided by a special Unicode character (tip provided by niczky12):
using Plots
unicodeplots();
n = 100;
x = [0:0.1:4*pi;];
for i = 1:30
y = sin.(x .+ (i/2));
plot(x, y, show=true, xlims = (0,4*pi), ylims = (-1,1))
sleep(0.01)
println("\33[2J")
end
A slight improvement might be this:
let
print("\33[2J")
for i in 1:30
println("\33[H")
y = sin.(x .+ (i/2));
plot(x, y, show=true, xlims = (0,4*pi), ylims = (-1,1))
sleep(0.01)
end
end

Need help fixing the plot for a simple curve() function code

I am trying to plot four separate functions on the same graph using the curve() function in r. I came up with the following code:
for (n in 1:4){
curve(n*sin(x), -5, 5, add = TRUE)
}
Unfortunately, when I try that, the resulting plot is extremely zoomed in on one arbitrary point of the graph (axes labels nor graph borders can be seen either). Just to clarify, there is no resulting error message in the console at all, the plot is just very zoomed in.
Instead of plotting them in a for loop, I tried plotting them separately to see if it would work and it did. I used:
curve(4*sin(x), -5, 5)
curve(3*sin(x), -5, 5, add = TRUE)
curve(2*sin(x), -5, 5, add = TRUE)
curve(1*sin(x), -5, 5, add = TRUE)
I had also thought that it could be that I used curve() in a for loop; however, it has worked for this code (demonstrating that the function doesn't seem to care whether I use it in a loop-type function):
for (n in 0:5){
curve(x^n, -3, 3, add = TRUE)
}
Besides trying out different code, I have closed my graphics device, turned it off with dev.off(), restarted RStudio, but none of it has worked.
If I were only using a sequence from 1 to 4, like I mentioned above, I wouldn't care about typing them separately; however, I plan on using a much larger range of sequences in the future (like 1:50 or 1:100 for example).
I'm using RStudio version 3.4.4 with macOS 10.14.2 if that matters.

Text not appearing on XTS plot

I'm having trouble adding some text to an plot of time series data in R using xts. I've produced a simple example of the problem.
My text() command seems to do nothing, whereas I can add a points to the plot. I've tried to keep the code simple by using defaults where possible
require(quantmod)
# fetch the data and plot it using default options
getSymbols('MKS.L')
plot(MKS.L$MKS.L.Close)
# try to add text - doesn't appear
text(as.Date('2012-01-01'),y=500,"wobble", cex=4)
# add a point - this does appear
testPos <- xts(600, as.Date('2012-01-01'))
points( testPos, pch = 3, cex = 4, col = "red" )
Any help appreciated - I'm pretty new to R and I've spent hours on this!
Not a direct answer, but the plot.xts function that comes with the xts package is not fully developed.
You're much better off using plot.zoo or plot.xts from the xtsExtra package (which was written as a Google Summer of Code project with the intention being to roll it into the xts package)
Either of these will work:
plot(as.zoo(MKS.L$MKS.L.Close))
text(as.Date('2012-01-01'),y=500,"wobble", cex=4)
#install.packages("xtsExtra", repos="http://r-forge.r-project.org")
xtsExtra::plot.xts(MKS.L$MKS.L.Close)
text(as.Date('2012-01-01'),y=500,"wobble", cex=4)

Reinitializing variables in R and having them update globally

I'm not sure how to pose this question with the right lingo and the related questions weren't about the same thing. I wanted to plot a function and noticed that R wasn't udpating the plot with my change in a coefficient.
a <- 2
x <- seq(-1, 1, by=0.1)
y <- 1/(1+exp(-a*x))
plot(x,y)
a <- 4
plot(x,y) # no change
y <- 1/(1+exp(-a*x)) # redefine function
plot(x,y) # now it updates
Just in case I didn't know what I was doing, I followed the syntax on this R basic plotting tutorial. The only difference was the use of = instead of <- for assignment of y = 1/(1+exp(-a*x)). The result was the same.
I've actually never just plotted a function with R, so this was the first time I experienced this. It makes me wonder if I've seen bad results in other areas if re-defined variables aren't propagated to functions or objects initialized with the initial value.
1) Am I doing something wrong and there is a way to have variables sort of dynamically assigned so that functions take into account the current value vs. the value it had when they were created?
2) If not, is there a common way R programmers work around this when tweaking variable assignments and making sure everything else is properly updated?
You are not, in fact, plotting a function. Instead, you are plotting two vectors. Since you haven't updated the values of the vector before calling the next plot, you get two identical plots.
To plot a function directly, you need to use the curve() function:
f <- function(x, a)1/(1+exp(-a*x))
Plot:
curve(f(x, 1), -1, 1, 100)
curve(f(x, 4), -1, 1, 100)
R is not Excel, or MathCAD, or any other application that might lead you to believe that changing an object's value might update other vectors that might have have used that value at some time in the past. When you did this
a <- 4
plot(x,y) # no change
There was no change in 'x' or 'y'.
Try this:
curve( 1/(1+exp(-a*x)) )
a <- 10
curve( 1/(1+exp(-a*x)) )

Resources