Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
582 views
in Technique[技术] by (71.8m points)

python - Plotly: How to avoid text in scatter plot being cut when exporting to PDF?

I have the following code to make an scatter plot using plotly as px

fig1 = px.scatter(utilities, x="Rating", y="Spread", facet_col="Duration",text="Security_Name")
fig1.update_layout(width=1200,title_text='Spread por rating y duración en el sector Utilities')
fig1.update_traces(textfont_size=8,textposition='top right')
fig1.show()

The problem is that when I export fig1 to PDF using this code:

fig1.write_image("Utilities.pdf")

Then most of the texts in "text" are cut because names are too long (they cannot be shortened). I have already tried using "top center" and "top left" but in either case the text is cut. I would really appreciate your help.

Screenshot

enter image description here

Update: Status after upgrading plotly: I have shortened the strings a little bit.

enter image description here

enter image description here

question from:https://stackoverflow.com/questions/66055382/plotly-how-to-avoid-text-in-scatter-plot-being-cut-when-exporting-to-pdf

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You haven't provided a dataset, but I've been able to reproduce your problem with a subset of a similar dataset px.data.stocks and an approach that resembles your use of px.scatter. And I'm assuming that your data has a long format, but that's not too important. What's important is this:

  1. You're absolutely right, the text will be cut using px.Scatter([...] text = <text>)
  2. There does surprisingly not seem to be a direct way to fix this.
  3. I've produced a work-around that's more than a bit hacky.
  4. The work-around turns this:

enter image description here

...into this:

enter image description here

The following snippet will reproduce the plot above. If this is something you can use, I'd be happy to elaborate on the details. But the short story is this: Faceted plots makes room for annotations made from add_annotations(), but not from annotations using px.Scatter([...] text = <text>).

Complete code:

# imports
import pandas as pd
import plotly.express as px
import plotly.io as pio

# data
df = px.data.stocks()
df = df[df.columns[:4]]
df2 = pd.melt(df.iloc[0:3],
              id_vars=['date'],
              value_vars=df.columns[1:],
              var_name='stock',
              value_name='value')

# your approach
fig = px.scatter(df2, x="date", y="value", facet_col="stock", text = 'stock')
fig.update_layout(width=1200,title_text='Spread por rating y duración en el sector Utilities')
fig.update_traces(textfont_size=8, textposition='top right')

# annotations
for c, d in enumerate(fig.data):
    for i, y in enumerate(d.y):      
        fig.add_annotation(x=d.x[i], y=d.y[i], text = str(d.x[i]),
                           font=dict(color="rgba(0,0,0,0)",size=10),
                           showarrow = False,
                           xanchor = 'left',
                           row = 1, col = c + 1
                          )
        
fig.write_image('c:plotlyplotssubnotation.pdf')
fig.show()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...