C137
C137

Reputation: 21

Square aspect ratio in 2D plots for static export

I want to create 2D scatter plots in plotly.py and export them as static .svg-files with a square aspect ratio. More specifically, I want to make the axis square in screen units (similar to this matplotlib question: Matplotlib scale axis lengths to be equal). Is there any way of achieving something similar using plotly? (Note that my x and y data are on a different scale)

I already tried to simply set the figure width and height to equal values, which works more or less fine if I have only one trace and no legend.

import numpy as np
import plotly.graph_objects as go

np.random.seed(42)

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=np.random.uniform(0, 1, 50), 
    y=np.random.randint(1, 100, 50), 
    mode='markers',
    ))


fig.update_layout(width=500, height=500)

# NOTE: Static image generation in plotly requires Kaleido (pip install -U kaleido)
fig.write_image("example.svg")

Output: example plot with one trace and fixed width and height

However, if I have mutliple traces and add a legend, I end up with a distorted plot:

import numpy as np
import plotly.graph_objects as go

np.random.seed(42)

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=np.random.uniform(0, 1, 50), 
    y=np.random.randint(1, 100, 50), 
    mode='markers',
    name="SomeLongTraceLabel1"
    ))

fig.add_trace(go.Scatter(
    x=np.random.uniform(0, 1, 50), 
    y=np.random.randint(1, 100, 50), 
    mode='markers',
    name="SomeLongTraceLabel2"
    ))

fig.update_layout(width=500, height=500)

# NOTE: Static image generation requires Kaleido (pip install -U kaleido)
fig.write_image("example.svg")

Output: example plot with two traces and a legend

I think it is possible to achieve this for 3D plots via the layout.scene.aspectmode="cubic" setting, but I could find a similar setting for 2D plots. Is there any way to make my plots automatically look like this: Desired Output without readjusting the figure width/height everytime with regard to the length of my legend items ?

Upvotes: 2

Views: 2158

Answers (1)

Adam
Adam

Reputation: 33

I had a similar problem... after seeing this: https://github.com/plotly/plotly.py/issues/70

I solved it as follows:

import plotly.express as px

fig = px.scatter(df, x='X', y='Z')
fig.update_xaxes(constrain='domain')  
fig.update_yaxes(scaleanchor= 'x')

Not sure if it will work for mulitple traces and legends.

Upvotes: 2

Related Questions