I am trying to create a waterfall plot (stacked line plot) in Makie.jl as shown in the attached image (Fig1.jpg).
I already know how to apply offsets to the lines to create the waterfall effect. However, I am struggling with how to add a secondary vertical axis on the right side to represent the “Emission Angle”.
In my case:
Left y-axis: Intensity (with offsets).
Right y-axis: Emission Angle (the parameter that distinguishes each line).
Could anyone point me to the idiomatic way to achieve this in Makie?
Any code snippets or examples would be very helpful. Thank you!
If you’re not actually using the left axis for numeric ticks, just flip the y axis to the right side and use a Label(fig[i, j, Left()], rotation = pi/2, ...) for the “Intensity” label.
If you do need a secondary axis, you can currently only achieve that by placing an Axis on top, hiding everything you don’t need and linking the non-twin axis in case you want to plot anything there that needs to be in sync.
I understand. I think there are quite a few situations where a second axis is needed—such as plotting spectrum with energy on the bottom axis and wavelength on the top axis, or plotting reaction rate as a function of the temperature T on the top axis and 1/T on the bottom axis. Thus,I had assumed that Makie would already support this. However, it seems this feature hasn’t been implemented in Makie yet. Is this possible in Plots?
Makie does support it, just like I described above, it’s just not wrapped into another convenience API. If we added one, it would do exactly that I think. If you do this often, you could wrap the couple commands needed into your own function, or think about opening a PR in Makie. I’m not sure if Plots has a keyword for this, probably.
You mean like this? Axis | Makie
Just the x linking is missing from there, which should be added in case the data does not have exactly the same extent.
No,
In the figure you referred to, the blue sine curve corresponds to the left axis, while the red curve corresponds to the right axis. What I need is a different situation: two vertical axes for a single curve. I would like to know how to link the left and right axes.
In your figure, for example, 1.0 on the left appears to correspond to 100 on the right, and −0.5 to −50. However, in reality, there is no actual relationship between the left and right axes.
What I am looking for is a way to ensure that the two axes are explicitly related through a well-defined transformation, so that each value on the left axis corresponds to a specific value on the right axis.
As I said previously, such situation occurs very frequently (at least in my field, solid state physics). Thus, I had assumed that the plotting library provided the way to do this.
If anyone knows how to achieve this, I would greatly appreciate your guidance.
Here is an alternate take, based on Jule’s answer,
where the yticks positions are driven by the first axis,
and the second axis tick labels are simply recalculated.
# ╔═╡ 4d7d8ae2-ec56-4cdc-bdf7-ffd364f63f4c
using WGLMakie
# ╔═╡ bb240c91-99c6-44cf-88c0-d3952d90a4a0
using Printf
# ╔═╡ be66327a-9bb8-46de-afd3-3570c687de1d
transf(x) = 100 * x - 320
# ╔═╡ ad5b249a-2dd3-11f1-85cb-ab504ea20a19
let
fig = Figure()
ax = Axis(fig[1, 1])
ax2 = Axis(fig[1, 1];
yaxisposition = :right,
ygridvisible = false,
ytickformat = values -> map(values) do value
@sprintf("%.0f", transf(value))
end
)
hidespines!(ax2)
hidexdecorations!(ax2)
linkyaxes!(ax, ax2)
lines!(ax, 0:0.1:10, sin)
fig
end
A major drawback is that when the mapping is somewhat complex, such as transf(x) = 101x - 320, the values displayed on the right ticks end up being quite non-standard. (Because -1.0 corresponds to -421, and thus, the “-421” is displayed)
In Jule’s way, this issue is overcome. Also, I believe the horizontal grid issue can be resolved by setting ygridvisible=false.
Regardless, it was helpful to see that this kind of alternative solution exists.