-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Please add a way to specify the location of multiple bits of text using container coordinates #3084
Comments
Annotations support here are the three ways of doing it: import plotly.express as px
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", facet_col="smoker", facet_row="sex")
fig.add_annotation(text="paper", showarrow=False, xref="paper", yref="paper", x=0.2, y=0.8)
fig.add_annotation(text="domain", showarrow=False, xref="x domain", yref="y domain", x=0.2, y=0.8)
fig.add_annotation(text="data", showarrow=False, xref="x", yref="y", x=10, y=6)
fig.show() |
Thank you Nicolas! I fear I did not explain what I needed very clearly, but I can easily add it to your example and show why none of these offer an obvious way to get what I need. I need to place two titles at the left edge of the container for the same graphic. I can get titles placed correctly using the following commands, but the second (or, should I add the second title by creating a second, almost blank graphic with the second title and overlaying it on the main graph)
I'd like to be able to, for example, write this:
but it throws an exception, since title only takes a dictionary or a title object and not a list. I need a strategy that works regardless of how much text and labelling there is in the left margin -- perhaps I could do this using paper coordinates by making estimates of the width of the labels based on max and min of the value shown on the y-axis to compute the width of the labels in characters and then transforming that to an approximate width in points, but this seems fragile and difficult. |
Correct, a figure has only one title. I would recommend you use the title for the upper text, and a text annotation for the lower text. |
Thanks Nicolas! My client requires that the top and bottom text both start at the left edge of the container. Can I specify that the bottom annotation go in the lower left corner of the container and that it's X coordinate be the same as the X coordinate of the top title at container coordinate X=0? Is there some general way to calculate for any graph that I might create e.g. paper coordinates that are equivalent to: How hard would it be for me to add container coordinate functionality to annotations? (I'm a data scientist and new to the plotly.py codebase.) Thanks! |
Ah, I see what you're trying to do, I'd forgotten that we introduced "container" coordinates when we added title positioning. You're right that annotations currently do not support container coordinates, only paper coordinates, which make it difficult to do what you need. In terms of adding this to Plotly yourself, this is certainly something we'd welcome, and would have to be implemented in Javascript within Plotly.js first, which would then make it available in Plotly.py. Here's a recent PR that added a new type of coordinate system to annotations, which you might use as a basis for implementing container coordinates in annotations/shapes/images: plotly/plotly.js#5014 |
Thanks Nicolas! Let me take a look and confer with my colleagues. If we figure this out, we'll put in a pull request or add to this thread with more questions. |
Hi! I worked on this with @rl-utility-man a while back. (I may be the one responsible for the choice of Plotly.) Basically, the visual standards require things like "the graph shall be x picas below the bottom of the title" and "the legend shall be y picas below the bottom of the source line, which shall be z picas below the bottom of the x-axis labels". Very easy to do in InDesign, which is what the standards were designed for, but not so easy in any Python (or R) plotting package I've found. All the elements have to be positioned relative to each other using absolute spacing. There's also things like "bars in bar charts shall be x picas wide, but the plot area shall be full width". And I believe (been a while since I looked at the specs) that the entire thing is supposed to be sized based on the plot area (again, absolute sizing), not the entire container. Which means that Plotly's (and any other system's) container sizing is non-ideal, since that needs to be determined by the plot area rather than the other way around. |
Yes, this is a problem we face fairly often when reconciling charting style guides with our model, which is decidedly not based on absolute sizes :) If you must absolutely guarantee absolute positioning of things, then your best bet would be to fix the height and width in pixels, turn off automargins and set margins absolutely, and then use those numbers to compute the coordinates of the corners in "paper" coordinates, which are then fixed for you. This means you will have to ensure that legends and labels etc all fit manually. Another option is to use Kaleido and the "no free lunch" :) |
Yup, manually tweaking distances was the best existing solution I could find. It's not quite automated, unfortunately. The Kaleido approach is interesting; I hadn't tried that. (Kaleido was mainlined into Plotly well into the project.) I looked at the feasibility of making a local copy of the Plotly codebase and adding absolute sizing functionality into plotly.js, but couldn't figure out where that code lived in the short rabbit hole I went down. Following PR5014 looks like it might give some insight into how that all works. Thanks! Adding in absolute sizing would be a solid selling point to corporate-level customers, I think; I imagine plenty of them have similar visual standards. I know we did back in my previous life as a management consultant. If it's possible to add the functionality into plotly.js and then enable it in Chart Studio... Man, providing every employee with Chart Studio and a template so they can easily create visuals-compliant graphics instead of sending it to a graphics artist would be an absolute game-changer. I'm no longer working on this, but it might make for an interesting personal side project in my off time. Admittedly, I only know Python and R, but hey. |
Hehe, yes, we do a lot of this :) |
Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for several years, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Thanks for your help - @gvwilson |
I just needed to add a source line at the bottom of a graphic and found this issue (and a general lack of clear tools or guidance for creating source lines) is still very much with us. The best way to create a source line at the bottom of the graph is to go to container coordinates for the y-axis and set it to a very small positive value -- say 0.01 -- just big enough to avoid cutting off the descending parts of characters like y, p, or q. Once you do that, you can't use container coordinates for your main title at the top of the figure -- instead, as far as I can tell, you still need to create it as an annotation. I haven't found a good way to line the source line up with the left most text in the graph, but can document some other options. I can try to submit the best code I've got for source lines to the documentation soon, but I'd welcome a more global fix; maybe even something like an "add_source_line" function with reasonable defaults. At the moment, I'm a Python coder but the fundamental feature request here is about the JavaScript On Plotly 5.24.1, the following suffices to show that annotation does not accept container coordinates. by throwing an exception on the second to last line of code.
|
@gvwilson Documentation PR 4873 shows a work around for the canonical problem that this issue proposes to solve elegantly. There are almost certainly more use cases for the proposed capability, but allowing programmers to use container coordinates on both a source line and a title is an obvious use case. I hope that is useful in deciding whether to reopen this. |
I have an application where I need to put one text string (the Y-axis label) in the top left corner and a second text string containing source information in the bottom left corner. Placing text at the left edge of the graph seems to require specifying container X-coordinate 0. Title obviously supports creating one such label in container coordinates, but only appears to support one piece of text. https://plotly.com/python/reference/layout/ add_annotation supports multiple pieces of text, but does not appear to support container coordinates. https://plotly.com/python/text-and-annotations/#positioning-text-annotations-absolutely
Please offer one tool that supports both multiple strings and container coordinates if it is not already possible to do so. If it is possible, please clarify the documentation. If this is a good Plotly codebase contribution 0 for a data scientist, let me know -- I can attempt it.
Thanks!
The text was updated successfully, but these errors were encountered: