I’m trying to use Plots and annotate
function to plot a numerical value onto the line.
plotly()
plot(sin)
annotate!(0, sin(0), text("0"))
It works not bad.
Furthermore, I want to put a text on the line with removing a part of a line on which to put a text.
I used a white square Unicode to fill a part of the line, and plot a text on it.
plotly()
plot(sin)
annotate!(0, sin(0), text("■", :white, 30))
annotate!(0, sin(0), text("0"))
Is there any more sophisticated way?
i.e. Control a background color of a text.
Late reply but I could not find an answer so I put together a short hack.
function annotatewithbox!(
fig::Plots.Plot,
text::Plots.PlotText,
x::Real, y::Real, Δx::Real, Δy::Real = Δx;
kwargs...)
box = Plots.Shape(:rect)
Plots.scale!(box, Δx, Δy)
Plots.translate!(box, x, y)
Plots.plot!(fig, box, c = :white, linestroke = :black, label = false; kwargs...)
Plots.annotate!(fig, x, y, text)
fig
end
There is definitely a better way to do it but it does the trick,
fig = plot(xlim = (-10, 10), ylims = (-10, 10))
annotatewithbox!(fig, text("hello how are you?!"), 2, 2, 4, 1)
3 Likes
FWIW, the workaround from @takuizum could be further improved by using a FULL BLOCK
Unicode character instead of the BLACK SQUARE
:
using Plots; gr()
fntcm = "Computer Modern"
fntsz = 12
default(fontfamily= fntcm)
str = "Hello Julia!"
n = length(str)
str0 = "█"^(n÷2+1) # FULL BLOCK Unicode character
plot(sin, legend = false)
annotate!(0, sin(0), text(str0,:white, fntcm,fntsz+2))
annotate!(0, sin(0), text(str, fntcm,fntsz))
One case where this hack breaks down is in the case where the string is multi-line.
In which case, n = length(str)
gives a spuriously large value and even worse, the “background” will not cover the whole text area.
See:
@takuizum of @rafael.guerra did you file an issue in the Plots.jl
repo? I think it makes sense to do.
I did not fill an issue.
Note that if we use a monospaced font such as “Courier”, then the character masking will be much easier to perform. See your example reproduced below, quick and dirty.
CODE: multi-line mask with monospaced font
using Plots; gr()
fntcm = "Courier"
fntsz = 8
default(fontfamily= fntcm)
str = "Hello Julia!\nThis is a second line\nand a third one!!!\nThis will result in a ton of whitespace"
n = length.(eachline(IOBuffer(str)))
str0 = join(hcat("█".^n), "\n") # FULL BLOCK Unicode character
plot(sin, legend = false)
annotate!(0, sin(0), text(str0,:white, fntcm, fntsz))
annotate!(0, sin(0), text(str, fntcm, fntsz))
1 Like