Plot an array of plots as subplots with Plots.jl - julia

Continuation of this thread: How to create an arbitrary number of subplots in Julia Plots
When I tried
using Plots
plot_array = Any[]
for i in 1:5
push!(plot_array, plot(rand(10))) # make a plot and add it to the plot_array
end
plot(plot_array)
I received Error:
MethodError: no method matching Plots.Plot{Plots.PlotlyBackend}(::Char, ::Char, ::Char, ::Char, ...)
Closest candidates are: Plots.Plot{Plots.PlotlyBackend}(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
What did I miss?

You need to "splat" the array of subplots in the last plot call using ...:
using Plots
plot_array = []
for i in 1:5
push!(plot_array, plot(rand(10)))
end
plot(plot_array...) # note the "..."
will produce something like

Related

Meshes.jl ERROR: UndefVarError: P2 not defined

I am trying to run some code from the Meshes.jl test source code, and it fails. What am I missing?
using Meshes
points = P2[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]
#ERROR: UndefVarError: P2 not defined
#Stacktrace:
# [1] top-level scope
# # REPL[2]:1
The code is from here:
https://github.com/JuliaGeometry/Meshes.jl/blob/bcc08b0b53622f2578c61561fef91153c05c393b/test/mesh.jl#L176
If you look at the runtests.jl file (https://github.com/JuliaGeometry/Meshes.jl/blob/bcc08b0b53622f2578c61561fef91153c05c393b/test/runtests.jl#L118), P2 is defined as an alias for Point{2, Float64}.
T = Float64
P1, P2, P3 = Point{1,T}, Point{2,T}, Point{3,T}
If you run these two lines, your example code will work.
Alternatively, you can define your points as:
points = Point[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]

Plot complex inequality in Julia

I have the mathematical expression |z - (-1)| < 1, with z element of Complexes, which is equivalent of a circle of radius 1 centered in (x,y)=(-1,0).
How can I plot this expression,
preserving the structure of the mathematical expression it was derived from, as much as
possible?
It should be an area.
What I tried so far:
using ImplicitEquations, Plots
f(a,b) = abs.(a+im*b - (-1))
plot(f<1)
The error I got:
ERROR: MethodError: no method matching isless(::typeof(f), ::Int64)
Closest candidates are:
isless(::Union{StatsBase.PValue, StatsBase.TestStat}, ::Real) at /home/buddhilw/.julia/packages/StatsBase/PGTj8/src/statmodels.jl:514
isless(::AbstractGray{T} where T, ::Real) at /home/buddhilw/.julia/packages/ColorTypes/6m8P7/src/operations.jl:31
isless(::ForwardDiff.Dual{Tx, V, N} where {V, N}, ::Integer) where
Tx at /home/buddhilw/.julia/packages/ForwardDiff/UDrkY/src/dual.jl:144
...
Stacktrace:
[1] <(x::Function, y::Int64)
# Base ./operators.jl:279
[2] top-level scope
# REPL[62]:1
There's not a lot of documentation for ImplicitEquations, but something stands out: you're not using the right operators. The package relies on unusual operators to represent math expressions with Julia functions: ≪ (\ll[tab]), ≦ (\leqq[tab]), ⩵ (\Equal[tab]), ≶ (\lessgtr[tab]) or ≷ (\gtrless[tab]), ≧ (\geqq[tab]), ≫ (\leqq[tab]).
So that fix would look like:
using ImplicitEquations, Plots
f(a,b) = sqrt((a+1)^2 + b^2)
plot(f ≪ 1)
Update:
f(a,b) = abs(a + im*b - (-1)) causes a method ambiguity error. f(a, b) = hypot(a+1, b), which is what abs calls, also causes the error. It looks like the issue is that at some point in hypot, OInterval(x::Ointerval) is called, but dispatch could not pick between (::Type{T})(x::T) where T<:Number in boot.jl or OInterval(a) in intervals.jl. Just redefining OInterval(a::Ointerval) = a won't work either because you run into another MethodError for decompose(::OInterval), which is a method intended for processing floats. Looking at the comments in intervals.jl, the dispatch seems like a work in progress.

Plotting graph in Julia with Float64 error

using Plots
α = 1
γ = 1.5
y(x) = -α(1-(γ*x)^(2))*exp(-0.5*γ*x^(2))
plot(y,-3,3)
I have no idea how to solve this error.
MethodError: objects of type Int64 are not callable
1. y(::Float64)#Local: 2
2. (::Base.var"#62#63"{RecipesPipeline.var"#7#8"{Symbol},typeof(Main.workspace315.y)})(::Float64)#operators.jl:875
3. (::PlotUtils.var"#27#29"{Base.var"#62#63"{Base.var"#62#63"{RecipesPipeline.var"#7#8"{Symbol},typeof(Main.workspace315.y)},RecipesPipeline.var"#9#10"{Symbol}}})(::Float64)#adapted_grid.jl:46
4. _broadcast_getindex_evalf#broadcast.jl:648[inlined]
5. _broadcast_getindex#broadcast.jl:621[inlined]
6. getindex#broadcast.jl:575[inlined]
7. copy#broadcast.jl:876[inlined]
8. materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,PlotUtils.var"#27#29"{Base.var"#62#63"{Base.var"#62#63"{RecipesPipeline.var"#7#8"{Symbol},typeof(Main.workspace315.y)},RecipesPipeline.var"#9#10"{Symbol}}},Tuple{Array{Float64,1}}})#broadcast.jl:837
9. #adapted_grid#26(::Int64, ::Float64, ::typeof(PlotUtils.adapted_grid), ::Any,
::Tuple{Float64,Float64})#adapted_grid.jl:57
10. adapted_grid(::Any, ::Tuple{Float64,Float64})#adapted_grid.jl:16
11. _scaled_adapted_grid(::Function, ::Symbol, ::Symbol, ::Int64, ::Int64)#user_recipe.jl:353
12. macro expansion#user_recipe.jl:293[inlined]
13. apply_recipe(::AbstractDict{Symbol,Any}, ::Function, ::Number,
::Number)#RecipesBase.jl:283
14. _process_userrecipes!(::Any, ::Any, ::Any)#user_recipe.jl:36
15. recipe_pipeline!(::Any, ::Any, ::Any)#RecipesPipeline.jl:70
16. _plot!(::Plots.Plot, ::Any, ::Any)#plot.jl:208
17. #plot#154#plot.jl:91[inlined]
18. plot(::Any, ::Any, ::Any)#plot.jl:85
19. top-level scope#Local: 3
short answer: the function should be defined as:
y(x) = -α * (1 - (γ * x)^2) * exp(-0.5γ * x^2)
The longer answer: the problem is not with the plotting because calling the y function would yield a similar error message. To answer the "how " to solve the error, I recommend testing the code bit by bit.
While Julia automatically understands a multiplication between a float and a variable (like the 0.5γ), Julia understood that you wanted to use α as a function and because α is an integer, it raised the error.

How to sort an array which has factors as ((x1, y1), (x2, y2)), according to each of lengths in Julia

I want to sort an array which has factors as ((x1, y1), (x2, y2)) and represents both of edges of a line, according to each of lengths in Julia.
I cannot write because of dim-difference between Python and Julia.
In Python, lines are sorted like follows;
lines = [ ((l[0][0], l[0][1]), (l[0][2], l[0][3])) for l in lines ]
lines.sort(key = lambda l: -sqrt((l[0][0]-l[1][0])**2+(l[0][1]-l[1][1])**2))
How to write the same process in Julia?
It seems you want this:
lines = [((a,b), (c,d)) for (a,b,c,d) in lines]
or this
lines = [((a,b), (c,d)) for (a,b,c,d) in eachrow(lines)]
(I would need an example of input lines and expected output example to be sure)
In order to sort it just use by kwarg:
sort!(lines, by=(((a,b), (c,d)),) -> -sqrt((a-c)^2+(b-d)^2))
or
sort!(lines, by=x -> -sqrt((x[1][1]-x[2][1])^2+(x[2][1]-x[2][2])^2))

Plotting non-injective labels on vertices in a graph in SageMath

I have a graph with vertices labeled by some pairs (a,b).
Can I plot it in such a way that I only see the first component "a" printed over each vertex?
I cannot just relabel, since my map (a,b)->a is not injective.
For a small example, take
G = Graph()
G.add_edge((1,1),(1,2))
The usual G.plot() gives (1,1)---(1,2).
Instead, how to produce only 1---1 ?
Plot a Sage graph with non-injective vertex labals
We describe a slightly tedious workaround, and then
a way to recover our comfort.
New class for vertices
One solution consists in writing a new class for vertices
that inherits from tuple and has a custom __str__ method
that returns a string for only the first entry in the tuple.
class MyVertex(tuple):
r"""
Class for vertices for special plotting of graphs.
Use with tuples, and only the first entry in the tuple
will be used as a vertex label when plotting the graph.
"""
def __init__(self, v):
self.vertex = v
def __str__(self):
return str(self.vertex[0])
Using this to define the vertices of the graph,
we obtain the desired behaviour.
Define a graph and add an edge from (1, 1) to (1, 2):
sage: G = Graph()
sage: G.add_edge(MyVertex((1, 1)), MyVertex((1, 2)))
When plotting the graph, both vertices have the label 1.
sage: G.plot()
Launched png viewer for Graphics object consisting of 4 graphics primitives
When listing the vertices, they still appear fully:
sage: G.vertices()
[(1, 1), (1, 2)]
Using usual graphs
To avoid having to use MyVertex explicitly, we write a graph-plotting
function that creates an intermediate "MyVertex"-style copy of a usual graph
for the sake of plotting.
def plot_graph(G):
r"""
Return a plot of this graph with special vertex labels.
The graph vertices are assumed to be tuples. The plot
uses the first component of each tuple as a vertex label.
"""
E = [(MyVertex(a), MyVertex(b)) for (a, b) in G.edges(labels=False)]
return Graph(E).plot()
Now compare:
sage: G = graphs.Grid2dGraph(3, 4)
sage: G.plot()
Launched png viewer for Graphics object consisting of 30 graphics primitives
sage: plot_graph(G)
Launched png viewer for Graphics object consisting of 30 graphics primitives

Resources