Connect points in for loop

Dear all

I am using PlotlyJS (I need its interactivity)

it is my code:

k1 = equ1
k2 = equ2
k3 = equ3
k4 = equ4

push!(k1_x, real(k1))
push!(k1_y, imag(k1))
push!(k2_x, real(k2))
push!(k2_y, imag(k2))
push!(k3_x, real(k3))
push!(k3_y, imag(k3))
push!(k4_x, real(k4))
push!(k4_y, imag(k4))
end

# Connect the four points to form a rectangle
push!(k1_x, k3_x[end])
push!(k1_y, k3_y[end])
push!(k2_x, k4_x[end])
push!(k2_y, k4_y[end])

trace1 = scatter(; x = k1_x, y = k1_y,
mode = "markers", name = "", line_color = "blue", line_width = 1.5)
trace2 = scatter(; x = k3_x, y = k3_y,
mode = "markers", name = "", line_color = "red", line_width = 1.5)
trace3 = scatter(; x = k2_x, y = k2_y,
mode = "markers", name = "", line_color = "green", line_width = 1.5)
trace4 = scatter(; x = k4_x, y = k4_y,
mode = "markers", name = "", line_color = "magenta", line_width = 1.5)

layout = Layout(; title = "Kharitonov Rectangles",
xaxis_title = "Real",
yaxis_title = "Imaginary",
showlegend = false)

plot([trace1, trace2, trace3, trace4], layout)
end

rectangles()

I want to connect red point to green with a line, green to pink, pink to blue and blue to red (create a square), but I tried several method which was not worked, I do not want to connect all reds point to gather in different frequencies and same for other points, I want to make an individual square in each frequency,

your help will be appreciated.

Are all of these lines of the same style and color?

1 Like

yes, in fact size and color is not important to be different, could be same

Would something like this work for you?

# ...
Lx = [k1_x k3_x k4_x k2_x k1_x fill!(similar(k1_x), NaN)] |> transpose |> vec
Ly = [k1_y k3_y k4_y k2_y k1_x fill!(similar(k1_x), NaN)] |> transpose |> vec
squares = scatter(; x = Lx, y = Ly, mode="lines")
#...
plot([trace1, trace2, trace3, trace4, squares], layout)
# ...
1 Like

thank you for your comment, I implement it as:

trace1 = scatter(; x = k1_x, y = k1_y,
mode = "markers", name = "", line_color = "blue", line_width = 1.5)
trace2 = scatter(; x = k3_x, y = k3_y,
mode = "markers", name = "", line_color = "red", line_width = 1.5)
trace3 = scatter(; x = k2_x, y = k2_y,
mode = "markers", name = "", line_color = "green", line_width = 1.5)
trace4 = scatter(; x = k4_x, y = k4_y,
mode = "markers", name = "", line_color = "magenta", line_width = 1.5)

Lx = [k1_x k3_x k2_x k4_x fill!(similar(k1_x), NaN)] |> transpose |> vec
Ly = [k1_y k3_y k2_y k4_y fill!(similar(k1_x), NaN)] |> transpose |> vec
squares = scatter(; x = Lx, y = Ly, mode="lines") 

layout = Layout(; title = "Kharitonov Rectangles",
xaxis_title = "Real",
yaxis_title = "Imaginary",
showlegend = false)

plot([trace1, trace2, trace3, trace4, squares], layout)
end

rectangles()

is it okay?

I recived following err:

ERROR: DimensionMismatch: vectors must have same lengths
Stacktrace:
 [1] hcat
   @ ./array.jl:2024 [inlined]
 [2] rectangles()
   @ Main ~/my_project_02/parameters_05:74
 [3] top-level scope
   @ ~/my_project_02/parameters_05:86

The lengths of k1_x throughk4_x must be the same. If some of them are longer you should truncate them to be the same.

1 Like

Here’s a self-contained demonstration.

julia> using PlotlyJS

julia> begin
           x = 0:0.025:1
           f(x) = x/(1+x)
           k1_x = x
           k1_y = f.(x)
           k2_x = x .+ 0.05
           k2_y = f.(x)
           k3_x = x
           k3_y = f.(x) .- 0.05
           k4_x = x .+ 0.05
           k4_y = f.(x) .- 0.05
           trace1 = scatter(; x = k1_x, y = k1_y, mode="markers")
           trace2 = scatter(; x = k2_x, y = k2_y, mode="markers")
           trace3 = scatter(; x = k3_x, y = k3_y, mode="markers")
           trace4 = scatter(; x = k4_x, y = k4_y, mode="markers")
           
           L1_x = [k1_x k3_x k4_x k2_x k1_x fill!(similar(k1_x),NaN)] |> transpose |> vec
           L1_y = [k1_y k3_y k4_y k2_y k1_y fill!(similar(k1_y),NaN)] |> transpose |> vec
           squares = scatter(; x = L1_x, y = L1_y, mode="lines", line_color="black")
           
           plot([trace1, trace2, trace3, trace4, squares])
       end
[ Info: Listening on: 127.0.0.1:6381, thread id: 1

2 Likes

Here is another version heavily based on Mark’s:

using PlotlyJS

t = 0:0.025:1

f(x) = x/(1+x)

k1 = map(x -> x + im*f(x), t)                  # equ1
k2 = map(x -> x + 0.05 + im*f(x), t)           # equ2
k3 = map(x -> x + im*(f(x) - 0.05), t)         # equ3
k4 = map(x -> x + 0.05 + im*(f(x) - 0.05), t)  # equ4
k = [k1 k2 k3 k4]

X = real.(k)
Y = imag.(k)

traces = GenericTrace[]

# Plot the points:
colours = ["blue", "red", "green", "magenta"]
for i=1:size(k,2)
    push!(traces,
        scatter(; x = X[:,i], y = Y[:,i],
            mode = "markers", name = "$i", line_color = colours[i]))
end

# Plot the squares:
squares = GenericTrace[]

V = [1, 2, 4, 3, 1] # vertex ordering of squares
for j in 1:size(k,1)
    push!(squares,
            scatter(; x = X[j,V], y = Y[j,V], mode="lines", line_color="black", showlegend=false))
end
append!(traces, squares)

# Create the plot:
plot(traces)
1 Like

Dear jd-foster and mkitti

Thank you for your replies, I tried both of them but not working for me,

I was focused on the form of the code, and the orders, and completely forgot about

One of the important points,

while I could not apply your suggestions and all possible methods, failed,

I back to the functions and checked the mathematical model.

These points must shape a rectangle, not a square which I did not note before,

so none of the suggested methods could help me.

sorry about that and if possible, help me by this point

The square part should not matter. Please provide sample data for us to proceed further.

Specifically, we need the values of kn_x and kn_y for n in 1, 2, 3, 4.

1 Like

k1, k2, k3 and k4 are characteristic equations. in order 3 as follows:

a3s^3+a2s^2+a1*s+a0

(just a3-a0 are different)

then we extract Im and Re parts to shape the 4 vertex of a rectangle:

push!(k1_x, real(k1))
push!(k1_y, imag(k1))
push!(k2_x, real(k2))
push!(k2_y, imag(k2))
push!(k3_x, real(k3))
push!(k3_y, imag(k3))
push!(k4_x, real(k4))
push!(k4_y, imag(k4))

Provide numbers or code to define them please.

1 Like

Here:

for w = 0:5:100
s = 1im * w # Use 1im for complex numbers in Julia

# Define the vertices of the Kharitonov rectangles
k1 = 0.27 * s^3 +4.45 * s^2 + 1.21 * s^1 + 114.3
k2 = 0.33 * s^3 + 5.44 * s^2 + 1.21 * s^1 + 114.3
k3 = 0.27 * s^3 + 5.44 * s^2 + 1.21 * s^1 + 114.3
k4 = 0.33 * s^3 + 4.45 * s^2 + 1.21 * s^1 + 114.3

in Matlab I could draw successfully but in Julia I cannot…

Try this:

w = 0:5:100
s = w * 1im
k1 = 0.27 .* s.^3 .+ 4.45 .* s.^2 .+ 1.21 .* s.^1 .+ 114.3
k2 = 0.33 .* s.^3 .+ 5.44 .* s.^2 .+ 1.21 .* s.^1 .+ 114.3
k3 = 0.27 .* s.^3 .+ 5.44 .* s.^2 .+ 1.21 .* s.^1 .+ 114.3
k4 = 0.33 .* s.^3 .+ 4.45 .* s.^2 .+ 1.21 .* s.^1 .+ 114.3

mode = "markers"

trace1 = scatter(; x = real(k1), y = imag(k1), mode)
trace2 = scatter(; x = real(k2), y = imag(k2), mode)
trace3 = scatter(; x = real(k3), y = imag(k3), mode)
trace4 = scatter(; x = real(k4), y = imag(k4), mode)

L1 = [k1 k3 k2 k4 k1 fill!(similar(k1),NaN + NaN*1im)] |> transpose |> vec
rects = scatter(; x = real(L1), y = imag(L1), mode="lines", line_color="black")
           
plot([trace1, trace2, trace3, trace4, rects])

Here’s another version that resembles your MATLAB version with lines of different colors.

julia> begin
           w = 0:5:100
           s = w * 1im
           p(a,b,c,d) = s->a*s^3 + b*s^2 + c*s + d 
           k1 = p(0.27, 4.45, 1.21, 114.3).(s)
           k2 = p(0.33, 5.44, 1.21, 114.3).(s)
           k3 = p(0.27, 5.44, 1.21, 114.3).(s)
           k4 = p(0.33, 4.45, 1.21, 114.3).(s)

           function draw_line(kn, km)
               L = [kn km fill!(similar(kn), NaN + 1im *NaN)]
               L = vec(transpose(L))
               x = real(L)
               y = imag(L)
               mode = "lines"
               scatter(; x, y, mode)
           end         
           plot(draw_line.(
               [k1, k3, k2, k4],
               [k3, k2, k4, k1]
           ))
       end

2 Likes

Thank you very much,
I could apply both versions,

  • using “.” before +, ^ and *

was a very important point …

Thank you for your great help.

Note that there is a shortcut to do this with @.

julia> begin
       k1 = @. 0.27 * s^3 + 4.45 * s^2 + 1.21 * s^1 + 114.3
       k2 = @. 0.33 * s^3 + 5.44 * s^2 + 1.21 * s^1 + 114.3
       k3 = @. 0.27 * s^3 + 5.44 * s^2 + 1.21 * s^1 + 114.3
       k4 = @. 0.33 * s^3 + 4.45 * s^2 + 1.21 * s^1 + 114.3
       end