Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying marker size in data unit for plotly

Tags:

python

plotly

I switched from matplotlib to plotly mainly to plot smooth animations in 2D/3D. I want to plot the motion of robots consisting of multiple circles/spheres.

The different body parts of the robot have different sizes and the circles need to represent that accurately. Is there a way in plotly to specify the size of the markers in data units? For example, I want to draw a 5m x 5m section in which circles with a radius of 0.1m are moving along different trajectories.

In matplotlib I know two alternatives. One is to use patches matplotlib.patches.Circle. The second option is to plot the points and scale their markersize correctly by taking the dpi into account (See the answers to this question for matplotlib).

A) Is it possible to animate shapes in plotly (3D)?

or

B) Is there a way to specify the size of the markers in data units or scale the sizeref attribute correctly?

# Point with radius 2 (approx.)
from plotly.offline import plot
import plotly.graph_objs as go

trace = go.Scatter(x=[4], y=[4],
                   mode='markers',
                   marker={'size': 260, 'sizeref': 1})  # ???

layout = dict(yaxis=dict(range=[0, 10]),
              xaxis=dict(range=[0, 10]))

fig = dict(data=[trace], layout=layout)
plot(fig, image_height=1000, image_width=1000)

A problem with scaling the markersize is that the image is only correct as long as you don't zoom in or out, because the markersize stays constant. Therefore the cleaner approach would be to specify the size of the circles directly in data units.

like image 325
scleronomic Avatar asked Oct 16 '22 10:10

scleronomic


1 Answers

Drawing circles is probably your best bet. Updating markersize with each resize would be a bit cumbersome. Here's something you could try for drawing circles

from plotly.offline import plot
import plotly.graph_objects as go

xy = [[4, 4], [1, 5], [2, 2]]
r = 0.1

fig = go.Figure()
kwargs = {'type': 'circle', 'xref': 'x', 'yref': 'y', 'fillcolor': 'black'}
points = [go.layout.Shape(x0=x-r, y0=y-r, x1=x+r, y1=y+r, **kwargs) for x, y in xy]
fig.update_layout(shapes=points)

fig.update_xaxes(range=[0, 10])
fig.update_yaxes(range=[0, 10])
fig.update_layout(width=1000, height=1000)
plot(fig)

Default (1st) and zoomed (2nd) view:

like image 169
busybear Avatar answered Nov 04 '22 00:11

busybear