-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Subplot titles #2746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
As a workaround, this can be done using layout annotations: https://plot.ly/javascript/text-and-annotations/#paper-referenced-annotations |
also related to #233 |
Annotations not working for subtitle |
@etpinard Is there a way to ensure the titles are centered above their subplots, using layout annotations? I can't find a good way to keep the titles centered for screens of different sizes. It would also be great to do this in a responsive way. Subplots with titles seems like a common use case, so I'm sure that this feature must be implemented somewhere! |
There are no words to describe how awkward the "easy" paper-referenced annotations solution is for achieving the simple and common task which is giving titles to subplots. Especially when you want each title to be precisely centered along its own subplot (apparently there is no way do to this without manually calculating the global Basically, subplots allow to get rid of complex and cumbersome calculations to get the positioning of the x/y axis elements right. If you dare want to add titles to your subplots (which is the case for, I don't know, let's say 80% of the time?), then these calculations are back again just for the sake of the titles, and in a much weirder way even (because of the borders, gaps, etc, that have to be take in to account). As @alexsax puts it, subplots with titles seem like a common use case, so maybe this would be a good candidate to simply "give suplots a title" before implementing some weird complicated edge case stuff that 0.0001% of users will ever need, like, pointing an annotated arrow to a bubble in a 3d-spheres chart so that the arrow dynamically follows the rotation of the whole chart... |
Update: it looks like there really is no way to center the title on its own subplot, as @alexsas puts it. Providing a annotations: [
{
xref: 'subplot',
subplot: [0],
x: 0.5,
xanchor: 'middle',
text: 'I am centered on the first subplot'
},
{
xref: 'subplot',
subplot: [1],
x: 0.5,
xanchor: 'middle',
text: 'I am centered on the second subplot'
},
] |
I agree this kind of thing is lacking in subplots - I'm new to plotly and after I saw how powerful it is I created a many-part subplot assuming subplot titling and legends would be easy, but when I got to that I went on a bit of a goose chase trying to figure it out. For now, the solution that is working for me (also based on annotations) makes use of the "domain"-splitting that happens when calling make_subplots. In python, I'm populating my subplots in a loop (starting at i=1) and using 'paper' anchors. My subplots only have one column, but you could do the same thing for getting the bottom position of a subplot using .domain[0] or the left/right using the corresponding xaxis attributes. Here are the most relevant lines within the loop:
...and then after end of loop:
|
This would be super incredibly massively turbo extra useful for our project Edit: @etpinard if you could explain what you mean by easy please - how do I make a paper-referenced annotation relative to subplot #3, for instance? I have a vertically-stacked list of "N" subplots, different Y axis for each. thank you My issue: if I use This is what I've done elsewhere: it's so hacky!
For this one I had to avoid the final shared x axis too:
|
I think there is a decent use case for most users to incorporate subplot titles, positioning etc... This will be a hassle if your plan to do something dynamic with plotly.js. Basically, you will be left to do all your calculations. For example, how many rows you want to have/ how many columns, how would you space your sub plots. Is the spacing going to be enough? The easy solution would be to create multiple Plotly.js Plots one for each subplot. This should be supported by plotly.js IMO. |
This issue has been tagged with A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort. Sponsorship range: $15k-$20k What Sponsorship includes:
Please include the link to this issue when contacting us to discuss. |
This should be out-of-the-box functionality. By now, users worldwide must have wasted thousands of hours trying to achieve what should be the very basic job of putting titles on subplots. |
Since we added the ability to do Here's the output and code: {
data: [{
mode: "markers",
x:[1,3,3],
y:[2,1,3],
xaxis: "x",
yaxis: "y"
},{
mode: "markers",
x:[1,3,3],
y:[2,1,3],
xaxis: "x2",
yaxis: "y2"
}],
layout: {
xaxis: {
domain: [0,0.48] ,
title: "X1"
},
yaxis: {
domain: [0,0.48],
title: "Y1"
},
xaxis2: {
domain: [0.52, 1],
anchor: "y2",
title: "X2"
},
yaxis2: {
domain: [0.52, 1],
anchor: "x2",
title: "Y2"
},
annotations: [
{
text: "X1/Y1 title",
showarrow: false,
x: 0,
xref: "x domain",
y: 1.1,
yref: "y domain"
},
{
text: "X2/Y2 title",
showarrow: false,
x: 0,
xref: "x2 domain",
y: 1.1,
yref: "y2 domain"
}
]
}
} |
Note that this issue will remain open, because the above is not a general-purpose solution for all subplot types e.g. polar, scene, ternary, mapbox, geo etc. |
I suspect that your solution might be missing the point. Unless I am missing the point :) I'm a very happy user of PlotlyJS.jl, but one annoying thing is that it uses |
My solution addresses the examples given above :) Did you mean grids i.e. using the |
Here's the same annotation solution with Note that in general, Plotly.js does not have a first-class concept of 2d cartesian "subplots". There are x-axes and y-axes and traces. If a trace exists at the intersection of a given x and y axis, then a subplot is implicitly drawn there (in my example here and the one above, there are 2 x-axes and 2 y-axes and 2 traces, and the way the trace-to-axis mapping is set up, we end up with one x1y1 subplot and one x2y2 subplot). The (Edit: for completeness... there could be traces that sit at the intersection of x1 and y2 or x2 and y1, in which case extra plotting areas would appear at the domain intersections of those axes) |
Okay. Yes I did mean Maybe I should ask (and maybe this is the wrong place): do you have a devdoc or something that explains how different widths, heights and placements are calculated? |
Got it. So above and beyond the fact that Plotly.js doesn't have a first-class "subplot" concept, Plotly.js also doesn't really do any kind of automated layout beyond automatically growing the plot margins to leave enough room for legends (by default) and 2d cartesian tick labels (opt-in via To address the kinds of concerns raise in this issue beyond the annotations-based approach I've outlined, we would need to do a lot of work within the engine (for which we would need a sponsor!):
To answer your last question, yes, some of this is documented in the Plotly.py documentation here https://plotly.com/python/figure-structure/ under "Positioning With Paper, Container Coordinates, or Axis Domain Coordinates" |
Currently my solution to this problem is adding subplot titles as text annotation within each own subplot, not in the overall plot. Set yref="paper" and yanchor = "bottom" and y = 1, so that the subplot title will be above each subplot. And set xref = "paper" and xanchor = "center" and x = 0.5, if you want to center the subplot title within each subplot. Or xanchor = "left" and x = 0, if you want to left align the subplot title. To get extra space for first row subplot titles, I add extra margin on the top of the overall plot. To get extra space for second row subplot titles, I add extra margin among the subplots. |
I have 3 subplots that are synchronized by sharing their XAxis. I want to add a title for each of the subplots like this :
See this pen : https://codepen.io/anon/pen/mKpNvO
The text was updated successfully, but these errors were encountered: