Reputation: 21
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
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