How to plot a graph using the "for"?

Hello everybody

In this example I put only the results of the variable r and managed to plot the graph

using JuMP, Plots

r = [69.60, 17.39, 0, 0],[0, 8.8, 2.1, 0],[0, 0, 8.8, 1.9], [16, 3.9, 0,0]
j = sum(r)
x = T
y = j
bar(x,y)

However, in the original model there are many variables with greater results than I used in the example above so it was necessary to use the for command.
This is the for that I’m using, it doesn’t give an error but it doesn’t generate the graph either

for t = 4
    m = sum(r)
    println(m)
    x = 1:4
    y = m
    plot(x,y)
end

Could someone help me pull the result of the sum of the variable I need to generate the graph?

Thanks!

for
    plot!()
end
plot!()
1 Like

To slightly elaborate, you will want to call plot() before your loop, then plot! in your loop to add to the existing plot,and then current() following your loop to display the plot

Note also that your foor loop isn’t actually looping, as t=4 is just one number (maybe you meant t=1:4?)

2 Likes

Hi and thank you for the suggestions @jling and @nilshg , but I think I was not clear in the example I mentioned above.
The model below is very similar to the original I’m working on. As in the example above, the for does not present an error, but neither does it generate the graph.

using JuMP,GLPKMathProgInterface, GLPK, Plots

FB = Model(solver = GLPKSolverMIP())

L = [12 ;60]
T = [0.25; 0.1; 0.1; 0.5; 0.75; 0.4]
D = [36; 22; 15]

@variable(FB, X[i = 1:2] >= 0)
@objective(FB,Max,sum(L[i]*X[i] for i=1:2))

for j in 1:3
    @constraint(FB, sum(X[i] for i=1:2) <= D[j])
end

print(FB)
solve(FB)
println("Objective value:  ", JuMP.getobjectivevalue(FB))
println("value:    ",  JuMP.getvalue(X[1:2])) 

#plot()
for i =  1:1
    j= getvalue(sum([(X[1:2])] for i= 1:2))
    println(j)
    x = 1:2
    y =(j)
    plot!(x,y)
end

Thanks!

I’m not sure if I understand precisely what you’d do, but as an extension of previous suggestions:

#.... your code
print(FB)
solve(FB)
println("Objective value:  ", JuMP.getobjectivevalue(FB))
println("value:    ",  JuMP.getvalue(X[1:2])) 

# You need an empty plot statement initially to have something to build on 
# when you do plot-bang,  i.e., plot!()
plot()
for i =  1:1
    j= getvalue(sum([(X[1:2])] for i= 1:2))
    println(j)
    x = 1:2
    y =(j)
    plot!(x,y)
end
# After the for-loop, you need to repeat the plot-bang
plot!()
2 Likes

Simpler example:

using Plots
#
x = range(0,2pi,length=100)
#
f(x;n=1) = sin(pi*n*x/4)
#
plot()      # Creates an empty plot which you can add plots to
#
for n in 1:4
    plot!(x,x->f(x;n=n))
end
#
plot!()      # Plots are not displayed from inside a for loop, so you need this additional plot! statement

leads to:

3 Likes

If your are using Jupyter you may use display to show the plot, like:

using Plots

p1 = plot() # Create a blank slate
for i=1:5
    plot!(p1, rand(4))
end
display(p1)

However, if you have a file foo.jl with that code inside, it won’t show the image if you run it with julia foo.jl. I don’t know why. In any case you could always save the figure with: savefig(p1, 'name.pdf') and watch it later

2 Likes

Hi @RaquelSantos, you can use display(plot(x,y) inside the for loop:

using Plots
for i=1:50
    display(plot(1:12, rand(12)))
end
1 Like

Alternative: CMDimData.jl

If you would prefer a system that has built-in support for multi-dimensional datasets, for example:

You are simulating something while varying multiple parameters

…so you can find out how they affect the outcome by plotting/post-processing data

Then you might want to try out CMDimData.jl:
GitHub - ma-laforge/CMDimData.jl: Parametric analysis/visualization +continuous-f(x) interpolation

It basically handles the “for” loop things for you when you plot, or run calculations (using MDDatasets.jl in the background). You just need to first get your data in a special DataRS recursive structure.

Example plotting without needing “for” loops

Sorry, I couldn’t get useful multi-dimensional data from your example, which is a bit confusing. So I “ported” the example from @BLI, more-or-less.

using CMDimData, MDDatasets, CMDimData.EasyPlot #Toolset
CMDimData.@includepkg EasyPlotInspect #Use InspectDR backend

Tsim = 2e-3 #End time of "Simulation"
t = DataF1(range(0,Tsim,length=1000)) #DataF1: Special {x,y} structure

#Generate data using a recursive structure for each "swept parameter":
ydata = fill(DataRS{DataF1}, PSweep("freq", [1, 2, 4, 8, 16] .* 1e3)) do 𝑓
	𝜔 = 2π*𝑓; T = 1/𝑓; 𝜙 = 0; A = 1.2
	sig = A * sin(𝜔*t + 𝜙)
	return sig
end;


#Describe plot (more control required than Plot.jl)
#------------------------------------------------------------------------------
plot = cons(:plot, title = "multi-dimensional data",
	xyaxes = set(xscale=:lin, yscale=:lin),
	labels = set(xaxis="X-Axis Label", yaxis="Y-Axis Label")
)

#Add ydata to plot:
push!(plot,
	cons(:wfrm, ydata, label="ydata"),
)

#Easily derive other quantities from data:
push!(plot,
	cons(:wfrm, xscale(ydata, 2)+3, label="xscaled+yshifted"),
	cons(:wfrm, xshift(ydata, 4e-3)-3, label="xshifted+yshifted"),
	cons(:wfrm, deriv(ydata/40e3)-6, label="dy/dt+yshifted"),
)

#Display plot itself:
EasyPlot.displaygui(:InspectDR, plot) #Can use other backends

Comments (downsides)

  • You can use PyPlot.jl or Plots.jl as a backend, but InspectDR.jl has the best support.
  • You might need to learn the CMDimData.EasyPlot API to get better control on plots.
  • You might need to learn the MDDatasets.jl API to see what is possible with its data encapsulation.
  • Overall API is not stabilized, an will likely change in the future (I don’t seem to change it often, though).
2 Likes

A more relatable answer

Looking back at your first example, I think I can make a more relatable solution using CMDimData.jl:

using CMDimData, MDDatasets, CMDimData.EasyPlot #Toolset
CMDimData.@includepkg EasyPlotInspect #Use InspectDR backend

#Your data:
r_x = [1, 2, 3, 4],[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3]
r = [69.60, 17.39, 0, 0],[0, 8.8, 2.1, 0],[0, 0, 8.8, 1.9], [16, 3.9, 0,0]

#Assuming each index of r[] represents a swept value of "t":
tsweep = PSweep("t", collect(1:4)) #Sorry, need "collect()" at the moment

#Build a "DataRS" structure using JuMP-generated data:
ydata = fill(DataRS{DataF1}, tsweep) do t
	return DataF1(r_x[t], r[t])
end;

y = sum(ydata)
@show y


#Describe plot (more control required than Plot.jl)
#------------------------------------------------------------------------------
plot = cons(:plot, title = "multi-dimensional data",
	xyaxes = set(xscale=:lin, yscale=:lin),
	labels = set(xaxis="X-Axis Label", yaxis="Y-Axis Label")
)

#Add ydata to plot:
push!(plot,
	cons(:wfrm, y, label="y"),
)

#Display plot itself:
EasyPlot.displaygui(:InspectDR, plot) #Can use other backends

image

1 Like