I still do not know, if a trick exist to use the command PlotlyJS.stem()
to plot stem lines in dB scaled diagrams, but I wrote a workaround. What is unclear to me, how to figure out which monospaced fonts are available on my system.
using PlotlyJS, DSP, Printf
# ------------------------------------------------------------------------------------------------------------------
# using LaTeXStrings # optional, if formulas are needed
# axes-configuration: https://plotly.com/python/axes/
# axes-configuration: https://plotly.com/python/reference/layout/xaxis/
# topics:
# - monospace bold font in legend
# - transparent background
# - stem lines in db-Scaled diagram
# note:
# - import into MS PowerPoint, to avoid misplaced letters: open svg in "inkscape" and paste as "inkscape svg"
# ------------------------------------------------------------------------------------------------------------------
n_frequ = 28
vec_frequ = collect(1 : n_frequ)
vec_ampl = DSP.Util.pow2db.(1e-10 .* vec(ones(1, n_frequ)))
f1THDA = 2
vec_ampl_THDA = copy(vec_ampl)
vec_ampl_THDA[f1THDA] = DSP.Util.pow2db(1)
vec_ampl_THDA[2*f1THDA] = DSP.Util.pow2db(0.1)
vec_ampl_THDA[4*f1THDA] = DSP.Util.pow2db(0.01)
vec_ampl_THDA[8*f1THDA] = DSP.Util.pow2db(0.001)
# --- local function to modify plot for e.g. svg and pdf output:
function _MyLibPlotlyLayoutHalf!(_hdl_trace::Plot{Vector{GenericTrace{Dict{Symbol, Any}}}, Layout{Dict{Symbol, Any}}, Vector{PlotlyFrame}},
_fn::AbstractString="foo.html", _transparent::Bool=true)
_, _fn_ext = splitext(_fn)
if ~(cmp(uppercase(_fn_ext), ".HTML") == 0)
_hdl_trace = PlotlyJS.relayout!(_hdl_trace,
template = templates.plotly_white,
height = 400,
width = trunc(Int, sqrt(2) * 400),
title_x = 0.5, # center title
title_font_size = 28,
xaxis_title_font_size = 20,
xaxis_linecolor = "black",
xaxis_linewidth = 2.0,
xaxis_ticks = "inside",
xaxis_tickfont_size = 18,
yaxis_title_font_size = 20,
yaxis_linecolor = "black",
yaxis_linewidth = 2.0,
yaxis_ticks = "inside",
yaxis_tickfont_size = 18,
# xaxis_constrain = "domain",
legend_font_size = 20,
# legend = PlotlyJS.attr(font_family = "monospace"),
# legend_font_family = "monospace",
)
if _transparent
_hdl_trace = PlotlyJS.relayout!(_hdl_trace,
paper_bgcolor = "rgba(0,0,0,0)", # transparent background
plot_bgcolor = "rgba(0,0,0,0)", # transparent background
)
end
else
@info("File extention is \".html\". No relayout done!")
end
return _hdl_trace
end
# function hdl_traces(_x::Vector{<:Number}, _y::Union{Array{<:Number}, Number}, _color::AbstractString="blue")
function _MyLib_Stem(_x::Vector{<:Number}, _y::Union{Array{<:Number}, Number}, _color::AbstractString="blue")
if length(_y) > 2
error("Y-vector needs to have only two elements")
end
_x = [_x, _x]
return PlotlyJS.scatter(; x = _x, y = _y, mode = "lines", line_color = _color, line_width = 0.5, showlegend = false)
end
# --- plot functions: THDA
function plot_THDA(_ampl_vec::Union{Array{<:Number}, Number})
hdl_traces = Vector{GenericTrace{Dict{Symbol, Any}}}(undef, 0)
# push!(hdl_traces, PlotlyJS.scatter(; x = vec_frequ, y = _ampl_vec, mode = "markers", marker_size = 10, showlegend = false))
push!(hdl_traces, PlotlyJS.scatter(; x = [vec_frequ[f1THDA]], y = [_ampl_vec[f1THDA]], mode = "markers", marker_size = 10,
name = "<b>1st harmonic = 2<sub>Hz</sub></b>"))
push!(hdl_traces, PlotlyJS.scatter(; x = [vec_frequ[2*f1THDA]], y = [_ampl_vec[2*f1THDA]], mode = "markers", marker_size = 10,
name = "<b>2nd harmonic = 4Hz</b>"))
push!(hdl_traces, PlotlyJS.scatter(; x = [vec_frequ[4*f1THDA]], y = [_ampl_vec[4*f1THDA]], mode = "markers", marker_size = 10,
name = "<b>3rd harmonic = 8Hz</b>"))
push!(hdl_traces, PlotlyJS.scatter(; x = [vec_frequ[8*f1THDA]], y = [_ampl_vec[8*f1THDA]], mode = "markers", marker_size = 10,
name = "<b>4th harminic = 16Hz</b>"))
for i_freq in eachindex(vec_frequ)
push!(hdl_traces, _MyLib_Stem(vec_frequ[i_freq], [minimum(_ampl_vec), _ampl_vec[i_freq]]))
end
# ---
plt_layout = PlotlyJS.Layout(
title_text = "THDA",
xaxis_title_text = "Frequency / Hz",
xaxis_zeroline = "false",
xaxis_anchor = "y",
xaxis_visible = true,
xaxis_linecolor = "black",
xaxis_linewidth = 2.0,
xaxis_mirror = true,
xaxis_constrain = "domain", # enforce the range to the specified range
# xaxis_range = collect(extrema(vec_frequ)),
xaxis_range = [0, n_frequ],
# --- y ---
yaxis_visible = true,
yaxis_title_text = "Amplitude / dB",
yaxis_constrain = "domain", # enforce the range to the specified range
# yaxis_range = collect(extrema(vec_ampl_THDA)),
yaxis_range = [-40, 10],
yaxis_fixedrange = true,
yaxis_linecolor = "black",
yaxis_linewidth = 2.0,
yaxis_mirror = true,
legend_font_family = "monospace",
# legend = PlotlyJS.attr(family="Arial, sans-serif", size=20, color="grey"),
)
return PlotlyJS.Plot(hdl_traces, plt_layout)
end
# --- plot THDA spectrum:
hdl_plt = plot_THDA(vec_ampl_THDA)
fn_plt = raw"c:\tmp\plt\THDA.svg"
_MyLibPlotlyLayoutHalf!(hdl_plt, fn_plt)
# hdl_plt = PlotlyJS.redraw(hdl_plt)
PlotlyJS.savefig(hdl_plt, fn_plt)
fn_plt = raw"c:\tmp\plt\THDA.pdf"
PlotlyJS.savefig(hdl_plt, fn_plt)