# Stem plots y-values expressed in dB / moving xaxis to a negative value

**URL:** <https://discourse.julialang.org/t/stem-plots-y-values-expressed-in-db-moving-xaxis-to-a-negative-value/87934>\
**Category:** General Usage\
**Tags:** plotlyjs\
**Created:** [September 28, 2022, 2:36pm UTC](https://discourse.julialang.org/t/stem-plots-y-values-expressed-in-db-moving-xaxis-to-a-negative-value/87934 "2022-09-28T14:36:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [September 28, 2022, 2:36pm UTC](https://discourse.julialang.org/t/stem-plots-y-values-expressed-in-db-moving-xaxis-to-a-negative-value/87934/1 "2022-09-28T14:36:23Z")

</div>

I would like to move the x-axis to a negative value and would like to have stem lines starting from the x-axis upwards, how can this be realized?  
Below a snippet that does not yet what I would like to achieve ☹

```julia
using PlotlyJS, DSP
# axes-configuration: https://plotly.com/python/axes/
# axes-configuration: https://plotly.com/python/reference/layout/xaxis/

n_frequ = 26 
vec_frequ = collect(1 : n_frequ)
vec_ampl = DSP.Util.pow2db.(1e-10 .* vec(ones(1, n_frequ)))

vec_ampl_THDA = copy(vec_ampl)
vec_ampl_THDA[2] = DSP.Util.pow2db(1)
vec_ampl_THDA[4] = DSP.Util.pow2db(0.1)
vec_ampl_THDA[8] = DSP.Util.pow2db(0.01)
vec_ampl_THDA[16] = DSP.Util.pow2db(0.001)

function plot_THDA()
    stem_THDA = PlotlyJS.stem(; x = vec_frequ, y = vec_ampl_THDA)
    plt_layout = PlotlyJS.Layout(
        title_text = "THDA",
        xaxis_title_text = "Frequency / Hz", 
        xaxis_zeroline = "false",
        yaxis_title_text = "Amplitude / dB", 
        yaxis_constrain = "domain", # enforce the range to the specified range
        yaxis_range = [extrema(vec_ampl_THDA)],
        yaxis_fixedrange = true,
    )
    return PlotlyJS.Plot(stem_THDA, plt_layout)
end

plot_THDA()

```

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [September 30, 2022, 7:08am UTC](https://discourse.julialang.org/t/stem-plots-y-values-expressed-in-db-moving-xaxis-to-a-negative-value/87934/2 "2022-09-30T07:08:58Z")

</div>

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.

```julia
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)

```
