Suggestion on this plot

Is there any easier way of doing this kind of plot?

Instead of just x_1, I would put a value, x_1 = 100 for example.

The way I think it would need to adapt a little the quiver plot and another plots, as here Plotting vector fields. But I don’t think it would be a good way of doing it.

1 Like

Easier than what?

This is not a plot. This is a diagram. Have you tried Luxor?

1 Like

OP’s annotated plot, could be conveniently generated using Plots.jl 's quiver!() and annotate!() together with LaTeXStrings.jl.

1 Like

I think it can be done quite easily using Kroki.jl.

I created a function that creates your diagram using Kroki. The input is a vector with the labels for x₁, x₂, etc. I believe the code is easy to understand. I used Pikchr to create the diagram:

using Kroki

function chart(x)
	# Function to get the subindex of a figure
	sub(i) = Char(0x2080+i)

	# First arrow
	chart = """
	arrow "s$(sub(0)) = 0" above
	"""
	
	unit(i, idx) = """
		circle fill black
		arrow <- up from last circle.n
		"$(x[idx])"
		arrow "xr$i " rjust down <- from last circle.s
		arrow down 85% right 85% from last circle.se
		"d$i"
		arrow "s$i$(idx==length(x) ? "=0" : "")" above right from last circle.e
	"""
	
	for idx in 1:length(x)
		i = sub(idx)
		chart *= unit(i, idx)
	end
	
	Diagram(:pikchr, chart)
end

With chart([100, 2, 3, 400, 5]) you get:

It’ easy to change the lengths of the arrows, the diameter of the circles or write the labels in italics.

11 Likes

Fyi, with Plots.jl, it takes 30 lines of code to produce:

Plots .jl code
using LaTeXStrings, Plots; gr(dpi=600)

const l, r, cθ, δ, fs = 1, 0.25, cosd(45), 0.12, 18
const vs, vxr, vx, vd = (l, 0), (0, l), (0, -l),(l*cθ, -l*cθ)

circle(x) = Shape(map(z -> z .+ (x + l + r, 0), Plots.partialcircle(0, 2π, 100, r)))

function unit_diagram!(x, xi_str, si_str, xri_str, di_str)
    plot!(circle(x), c=:black, fill=:black)
    quiver!((x+l+2r, 0), quiver=([vs[1]],vs[2]), c=:black, arrow=:closed)
    quiver!((x+l+r, l+r), quiver=([vx[1]],vx[2]), c=:black, arrow=:closed)
    quiver!((x+l+r, -(l+r)), quiver=([vx[1]],-vx[2]), c=:black, arrow=:closed)
    quiver!((x+l+r+r*cθ, -r*cθ), quiver=([vd[1]],vd[2]), c=:black, arrow=:closed)
    annotate!(x+l+r-δ/2, -0.8*l, text(xri_str, :right, fs))
    annotate!(x+l+r, l+r+δ, text(xi_str, :center, fs))
    annotate!(x+2l, δ, text(si_str, :center, fs))
    annotate!(x+(l+r)*(1+cθ)+δ, -(l+r)*cθ - δ, text(di_str, :center, fs))
end

function plot_diagram(n, vstr)
    p = plot((0,0), ratio=:equal, framestyle=:none, size=(1200,600)) # size=(1200,600)
    quiver!((0,0), quiver=([vs[1]],vs[2]), c=:black, arrow=:closed)
    annotate!(l/2, δ, text(L"s_0 = 0", :center, fs))
    for i in 1:n
        si = i == n ? L"s_%$i = 0" : L"s_%$i"
        stri = vstr[i]
        !isempty(stri) && (stri = " = $stri")
        unit_diagram!((i-1)*(l+2r), L"x_%$i%$stri", si, L"xr_%$i", L"d_%$i")
    end
    return p
end

plot_diagram(5, ["100", "", "", "", ""])
4 Likes