PlotlyJS: modify parts of the plot

Today I wanted to figure out, how to modify the axis type of one specific subplot.
My question is, how do I figure out stuff like this, if I am not successful to find anything by internet search?
What is the best approach? Trial and error? Or reading the Julia source code of the package PlotlyJS? Or is there some documentation of which I am not aware of?

In the end I figured out how to acchieve this task, here some code that might help other to understand better, how to analyse the structure of the plot object:

using PlotlyJS
hdl_trace1 = scatter(x=[1, 2], y=[1, 2], name="(tr1)")
hdl_trace2 = scatter(x=[1, 2], y=[2, 3], name="(tr2)")
hdl_trace3 = scatter(x=[1, 2], y=[3, 4], name="(tr3)")
# --- plot with three subplots in one column:
hdl_plt = make_subplots(rows=3, cols=1, specs = [ Spec(kind="xy") missing; Spec(kind="xy") missing; Spec(kind="xy") missing])
add_trace!(hdl_plt, hdl_trace1, row=1, col=1)
add_trace!(hdl_plt, hdl_trace2, row=2, col=1)
add_trace!(hdl_plt, hdl_trace3, row=2, col=1)

# --- modify title:
relayout!(hdl_plt, title_text="Example subplots: two row by one colum plot")
# --- modyfy xaxis_type of 2nd subplot:
relayout!(hdl_plt, xaxis2_type="log")

# --- investigate plot handle / plot object:
for (a,b) in hdl_trace2
    println(a)
end

hdl_trace2["y"]
hdl_trace2["type"]
hdl_trace2["name"]
hdl_trace2["x"]


for (a,b) in hdl_plt.plot.layout
    println(a)
end

for (a,b) in hdl_plt.plot.layout.xaxis2
    println(a)
end

hdl_plt.plot.layout.xaxis2
hdl_plt.plot.layout.template.layout.xaxis

The official Plotly figure reference is useful (although it helps if you know what you need already :thinking:):

2 Likes

An alternative is PlotlyJS.docs(), which opens a new local window.
(Actually, still not working: PlotlyJS.docs() · Issue #161 · JuliaPlots/PlotlyJS.jl · GitHub)
You can open in your browser
~/.julia/packages/PlotlyJS/4jzLr/deps/schema.html
for the same (change 4jzLr to match your local installation).

1 Like

Apart from the very good suggestion from @jd-foster about the single-page reference which I often resort to, I usually also look at the JavaScript Documentation page as it often has many more examples than the julia one.
The core library is anyway written in JS and what PlotlyJS does is mostly translating from its julia synthax to the equivalent javascript one to call the library.
I find that once you get an understanding on how the syntax mapping between JS and Julia works (which is quite straightforward in my opinion and can be better understood from the PlotlyJS documentation), it is very easy to translate Javascript Examples to Julia equivalents.

1 Like

This is a great point: I also do precisely as you describe.

Today I tried to define the axis as equally scaled and I struggled about following issue,
I have not figured out how to specify the range of the axis.

plt_layout = PlotlyJS.Layout(;
      xaxis_range = [0, 1],
      yaxis_range = [0, 1],
)

Is not always sufficient:

Following my example script:

using PlotlyJS
# Example for fixed Ratio Axes
# source: https://plotly.com/python/axes/#fixed-ratio-axes
# ---
x_vec = 0:0.1:pi
y1_vec = cos.(x_vec)
y2_vec = sin.(x_vec)
y_range = [min(minimum(y1_vec), minimum(y2_vec)), max(maximum(y1_vec), maximum(y2_vec))]

function plot_graph()
    hdl1 = PlotlyJS.scatter(; x= x_vec, y = y1_vec, name = "cos")
    hdl2 = PlotlyJS.scatter(; x= x_vec, y = y2_vec, name = "sin")
    plt_data = [hdl1, hdl2]
    plt_layout = PlotlyJS.Layout(;
        title_text          = "Fixed Ratio Axes",
        xaxis_title_text    = "Angle / rad",
        xaxis_range         = [x_vec[1], x_vec[end]],
        xaxis_showgrid      = true, 
        yaxis_title_text    = "Amplitude / -",
        yaxis_range         = y_range,
        yaxis_showgrid      = true,
        # --- Fixed Ratio Axes Configuration
        yaxis_scaleanchor   = "x",
        yaxis_scaleratio    = 1,
        # --- Legend Configuration
        # legend_y = 0.95, legend_x = 0.9, 
        # legend              = PlotlyJS.attr(x=0.1, y=0.5), # fraction of plot pane
        # margin_r = 60, # right margin of canvas, legend is also moving
    )
    hdl_plt = PlotlyJS.Plot(plt_data, plt_layout)
    return hdl_plt
end

plot_graph()

I think I found the answer:
compressed-domain

plt_layout = PlotlyJS.Layout(;
      xaxis_range     = [0, 1],
      xaxis_constrain = "domain",
)

Add this:

xaxis_range         = [x_vec[1], x_vec[end]],
xaxis_constrain     = "domain",  # <---
xaxis_showgrid      = true,
1 Like

Thanks, jd!

another wanted feature are multiple y-axis, here is my first example:

using PlotlyJS
# Multiple Axes: https://plotly.com/python/multiple-axes/#multiple-axes

function plot_multiple_yaxis()
    scatter1 = PlotlyJS.scatter(;x = 1:10, y = randn(10),       name= "RND1")
    scatter2 = PlotlyJS.scatter(;x = 1:10, y = 2*randn(10),     name= "RND2", yaxis= "y2")
    scatter3 = PlotlyJS.scatter(;x = 1:10, y = 1000*randn(10),  name= "RND2", yaxis= "y3")
    scatter4 = PlotlyJS.scatter(;x = 1:10, y = 2000*randn(10),  name= "RND2", yaxis= "y4")
    plt_traces = [scatter1, scatter2, scatter3, scatter4]
    mylayout = Layout(
        title_text       = "Multiple Y Axis Example",
        xaxis_title_text = "xaxis title",
        xaxis_domain     = [0.12, 0.88],
        yaxis_title_text = "yaxis title",
		# yaxis_type       = "log",
        yaxis2 = PlotlyJS.attr(
            title      = "yaxis2 title",
			# type       = "log",
			# range      = [0, 1],
            overlaying = "y",
            side       = "left",
            anchor     = "free",
            position   = 0.05,
            ),
        yaxis3 = PlotlyJS.attr(
            title      = "yaxis3 title",
            # type       = "log",
            # range      = [0, 1],
            overlaying = "y",
            side       = "right",
            anchor     = "free",
            position   = 0.95,
            ),
        yaxis4 = PlotlyJS.attr(
            title      = "yaxis4 title",
            # type       = "log",
            # range      = [0, 1],
            overlaying = "y",
            side       = "right",
            ),
            
        )
    return PlotlyJS.Plot(plt_traces, mylayout)
end
plot_multiple_yaxis()