Hi all,
I have this code:
using Plots, LaTeXStrings
gr()
f(x)=floor(x)
plot(f,0,10,ylim=(-12,12))
Since [ x ] denotes the gretest integer less than or equal to x, I want to plot it like this:
Anyone know how?
Hi all,
I have this code:
using Plots, LaTeXStrings
gr()
f(x)=floor(x)
plot(f,0,10,ylim=(-12,12))
Since [ x ] denotes the gretest integer less than or equal to x, I want to plot it like this:
Anyone know how?
One way:
using Plots; gr()
xp = [[i, i+1 - 5*eps()] for i in -12:11]
p = plot(ylim=(-12,12), framestyle = :origin)
for x in xp
plot!(x, floor.(x), c=:black)
scatter!(x, floor.(x), ms=3, msc=:black, mc=[:black, :white])
end
p
NB: it would be faster not to loop and plot everything in one go. It would require inserting NaNs at the breaks.
Creating step functions is not as simple as just using floor().
I tried to reproduce the original plot (not the best code, but it has been fun):
f(x) = floor(x)
x = -5:1:4
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x \rfloor", legend=:bottomleft,legend_foreground_color=:white, legend_font_color=:blue, color=:blue, showaxis=false, tickfontcolor=:white)
# axis and
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
annotate!(-.2, -.2, ("0", 7))
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue, lw=2)
scatter!(x[i], y[i], marker=:circle, markersize=8, label="")
end
scatter!(x[1:end-1], y[1:end-1], markersize=3, markercolor=:blue, label="")
scatter!(x[2:end], y[1:end-1], markersize=3, markercolor=:white, label="")
Here is a version without the plot loop using NaN
at the breaks:
using Plots; gr()
x = -12:12
xp = [[i, i+1 - 5*eps(), NaN] for i in x[1:end-1]]
xx = collect(Iterators.flatten(xp))
yy = floor.(xx)
plot(xx, yy, c=:black, label=false, framestyle = :origin)
scatter!(xx', yy', msc=:black, mc=[:black :white :white], ms=3)
It is really beautiful,
I want to ask
plot(x[1:2], [y[1], y[1]]
why there are two y[1] ? I want to know the details behind it.
Note that if you want the axes centered at the origin, you should use plot argument: framestyle = :origin
. NB: updated in examples above
Thanks for the explanation.
Because the first step goes from point (x[1], y[1])
to (x[2], y[1])
. It’s the same for the rest of the steps inside the for loop.
I have cleaned my version a little bit (thanks to @rafael.guerra):
# Plot configuration
plot(legend_title=L"f(x) = \lfloor x \rfloor", legend=:bottomleft,legend_foreground_color=:white, legend_title_font_color=:blue, color=:blue, framestyle=:origin, ticks=x)
# Steps drawing
for i in 1:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue, lw=2)
end
# Points at the beginning ot the steps
scatter!(x[1:end-1], y[1:end-1], markersize=3, markercolor=:blue, label="")
# End points
scatter!(x[2:end], y[1:end-1], markersize=3, markercolor=:white, label="")
# Adds '0' close to origin
annotate!(-.22, -.26, ("0", 8))
I’m sure it could be improved, but I think it’s quite close to the original.
Tried this in Jupyter Notebook and compare with your old code.
It is simpler, so we can remove the old
f(x) = floor(x)
x = -5:1:4
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x \rfloor", legend=:topleft,legend_foreground_color=:white, legend_font_color=:blue3, color=:blue3, showaxis=false, tickfontcolor=:white)
# axis and
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue3, lw=2)
scatter!(x[i], y[i], marker=:circle, markersize=8, label="")
end
Hi @runjaj
I am trying to plot [x + 1/2]
do you know what to edit in your code? Thanks
Hi!
One simple option is just changing the function to:
f(x) = floor(x + 1/2)
And the step of the x
to 0.5
:
x = -5:.5:4
In this case, you’ll get:
Is this what you want?
If you want to avoid plotting the central point of each step, the easiest way is set x
to:
x = -5.5:1:4.5
This is the code I used:
f(x) = floor(x + 1/2)
x = -5.5:1:4.5
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x + 1/2 \rfloor", legend=:bottomleft,legend_foreground_color=:white,
legend_font_color=:blue, color=:blue, showaxis=false, tickfontcolor=:white)
# axis
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
# Scale values
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
annotate!(-.2, -.2, ("0", 7))
# Plot function
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue, lw=2)
end
Javier
I actually tried this
using Plots, LaTeXStrings, Plots.PlotMeasures
gr()
f(x) = floor(x + 1/2)
x = -5:.5:4
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x \rfloor", legend=:topleft,legend_foreground_color=:white, legend_font_color=:blue3, color=:blue3, showaxis=false, tickfontcolor=:white)
# axis and
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue3, lw=2)
scatter!(x[i], y[i], marker=:circle, markersize=8, label="")
end
and it returns error:
LoadError: Cannot convert Float64 to series data for plotting
seems the scatter function is problematic for using float or decimal value.
Then I try your code:
using Plots, LaTeXStrings, Plots.PlotMeasures
pyplot()
f(x) = floor(x + 1/2)
x = -5.5:1:4.5
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x + 1/2 \rfloor", legend=:bottomleft,legend_foreground_color=:white,
legend_font_color=:blue, color=:blue, showaxis=false, tickfontcolor=:white)
# axis
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
# Scale values
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
annotate!(-.2, -.2, ("0", 7))
# Plot function
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue, lw=2)
end
the GUI window is not showing up, weird, but the REPL shows it is done…
scatter
expects a vector of numbers, you need scatter!([x[i]], [y[i]])
although at that point you might as well just pull it out of the loop and write scatter!(x[2:length(x)-1], y[2:length(x)-1])
(which will also make the plot window show up as per my response in the other thread)
I just read your reply more carefully and after lots of trial it works with this code:
using Plots; gr()
f(x) = floor(x + 1/2)
x = -5.5:1:4.5
y = f.(x)
plot(x[1:2], [y[1], y[1]], label=L"f(x) = \lfloor x + 1/2 \rfloor", legend=:bottomleft,legend_foreground_color=:white, legend_font_color=:blue, color=:blue, showaxis=false, tickfontcolor=:white)
# axis and
hline!((0,0), color=:black, label="")
vline!((0,0), color=:black, label="")
for i in x
if i!= 0
annotate!(i,-0.2, (i, 7))
end
end
for i in y
if i != 0
annotate!(-.2, i, (i, 7))
end
end
annotate!(-.2, -.2, ("0", 7))
for i in 2:length(x)-1
plot!(x[i:i+1], [y[i], y[i]], label="", color=:blue, lw=2)
end
scatter!(x[1:end-1], y[1:end-1], markersize=3, markercolor=:blue, label="")
scatter!(x[2:end], y[1:end-1], markersize=3, markercolor=:white, label="")