简体   繁体   中英

plotly paint outside of figure

I don't know if the title describes my problem, but that's my best guess.

creating a gannt plot in plotly is easy enough ( https://plotly.com/python/gantt/ ).

Additionally, I want to indicate certain critical events. As those are non-specific to categories, I don't want them to refer to a certain category on the y-axis. So I want to go with vertical lines. That is still easy enough ( add_vline ). But those lines also need to labeled with the event name, the events usually have very long names. That can be done by annotating the vertical lines. As the event names are very long, I thought that offsetting them in y-direction would be a good idea.

The end-result should look like this: 在此处输入图片说明 Labeling the vertical lines works well for roughly the first three events, but then the annotations get out of the canvas(?) allocated for the graph. I tried to indicate this with the black dashed frame.

Consequently, the texts "text that gets cut off" and "no chance" are not displayed. How can I fix this? I read that the annotations are not really graph objects but and as such, the dimensions of the graph are not expanded to the annotations' coordinates. But I also found no "text graph objects" in plotly.

You should be able to get what you want through a combination of shapes , annotations , and a correct adjustment of margins . The setup below does just that, and annotates the shapes with an increasingly negative offset to the zero line using y = -0.2-(i/10) and yref = 'paper' in fig.add_annotation() . As it now stands, the approach isn't very dynamic with regards to number of annotated lines, but we can take a closer look at that if this figure does in fact represent the essence of what you're looking for:

在此处输入图片说明

Complete code:

import plotly.express as px
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task")
fig.update_yaxes(autorange="reversed")

events = [{'date':'2009-02-01', 'annotation': 'some important information', 'color':'red'},
          {'date':'2009-04-01', 'annotation': 'some very important stuff', 'color':'green'}]

for i, e in enumerate(events):
    fig.add_shape(type = 'line', x0 = e['date'], x1 = e['date'], y0 = 0, y1 = 1, yref = 'paper',
                  line = dict(color = e['color']))
    fig.add_annotation(x = e['date'], y = -0.2-(i/10), text = e['annotation'],
                      yref = 'paper', showarrow = False,
                      font=dict(color=e['color'],size=12))

fig.update_layout(margin=dict(l=25,
                                r=25,
                                b=100,
                                t=25,
                                pad=4),
                  paper_bgcolor="LightSteelBlue")
    
fig.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM