question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Line animations fail in some frames for some lines.

See original GitHub issue

OS: OSX 10.13.2 Browsers: Chrome/Firefox/Safari latest

plotly-bug

As you can see in this gif, most of the frames animate properly. Some however have the lines “jumping” to their final values rather than being smoothly transitioned.

This animated scatter is being created from the Python API, but I suspect this is more appropriate for the js side to investigate. (Correct me if I’m wrong).

Here is the script to recreate the above chart.

Notes

  • The issue seems to be largely independent of how many lines are being drawn. (You can change line_count below to see that).
  • The issue goes away if the values remain constant within each line. Comment out line 43 to see that.
import numpy as np
import colorlover as cl
from plotly.offline import plot

sim_duration = 20.0
time_inc = 0.1
line_count = 120
times = np.arange(0.0, sim_duration, time_inc)

# Setting colors for plot.
potvin_scheme = [
    'rgb(115, 0, 0)',
    'rgb(252, 33, 23)',
    'rgb(230, 185, 43)',
    'rgb(107, 211, 100)',
    'rgb(52, 211, 240)',
    'rgb(36, 81, 252)',
    'rgb(0, 6, 130)'
]
# It's hacky but also sorta cool.
c = cl.to_rgb(cl.interp(potvin_scheme, line_count))
c = [val.replace('rgb', 'rgba') for val in c]
c = [val.replace(')', ',{})') for val in c]


def get_color(trace_index: int) -> str:
    # The first and every 20th trace should be full opacity
    alpha = 0.2
    if trace_index == 0 or ((trace_index + 1) % 20 == 0):
        alpha = 1.0
    color = c[trace_index].format(alpha)
    return color

# Per Motor Unit Force

start = np.ones((line_count, len(times)))
inds = np.reshape(np.arange(1.0, 41.0, 40 / len(times)), (1, len(times)))
vals = (-np.log(inds) + 4) / 0.18
vals = np.repeat(vals, line_count, axis=0)


all_array = np.ones((line_count, len(times))) * np.reshape(np.arange(0.0, 35.0, 35 / line_count), (line_count, 1))
all_array += vals  # <---- COMMENT OUT TO REMOVE CURVE
data = []
annotations = []
anno_offsets = {
    0: 20,
    19: 30,
    39: 40,
    59: 45,
    79: 17,
    99: 56,
    119: 170
}

max_y = np.amax(all_array)
for i, t in enumerate(all_array):
    trace = dict(
        x=times[:1],
        y=t[:1],
        name=i + 1,
        marker=dict(
            color=get_color(i)
        ),
        mode='lines'
    )
    data.append(trace)

frames = []
for i in range(1, len(times), int(1 / time_inc)):
    frame_data = []
    for j, t in enumerate(all_array):
        trace = dict(
            x=times[:i],
            y=t[:i],
            name=j + 1,
            marker=dict(
                color=get_color(j)
            ),
            mode='lines'
        )
        frame_data.append(trace)

    frame = dict(
        data=frame_data
    )
    frames.append(frame)

layout = dict(
    title='Motor Unit Forces by Time',
    yaxis=dict(
        title='Motor unit force (relative to MU1 tetanus)',
        range=[0, max_y],
        autorange=False
    ),
    xaxis=dict(
        title='Time (s)',
        range=[0, sim_duration],
        autorange=False
    ),
    updatemenus=[{
        'type': 'buttons',
        'buttons': [{
            'args': [
                None,
                {'frame': {'duration': 300, 'redraw': False},
                 'fromcurrent': True,
                 'transition': {'duration': 200, 'easing': 'linear'}
                 }
            ],
            'label': 'Play',
            'method': 'animate'
        }]
    }]
)
layout['annotations'] = annotations

fig = dict(
    data=data,
    layout=layout,
    frames=frames
)

plot(fig, filename='bug.html', validate=False)

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
etpinardcommented, Jul 13, 2018
1reaction
alexcjohnsoncommented, Jul 12, 2018

do you think patching the above line in line_points.js and documenting this “equal-length” workaround is an ok solution to the problem

Yes, seems like line.simplify: false should mean that anyway. This would be important for other animations too, even if the number of points really is constant but there’s a chance that sometimes neighboring points could match.

or should we try to find a better way to smoothly transition line paths of different coordinate lengths?

That would be great, but sounds theoretically ambiguous. How can we tell if an increase in number of points is an append, prepend, insert, or something else? All of those would imply different animations.

Read more comments on GitHub >

github_iconTop Results From Across the Web

r - animating only one line and two static lines in a plot with ...
To me here are arising some questions: How can I achieve that only my black line (y vector) is animated and the two...
Read more >
Create Beautiful Line Animations in After Effects - YouTube
This video shows how to animate lines to really spice your motion graphics in Adobe After Effects.The secret to do doing this is...
Read more >
How I do clean up lines for 2D Animation - YouTube
In this video I talk about how I clean up lines for my 2D animation.Build CONFIDENCE in your LINE strokes with these drawing ......
Read more >
2 EASY Line ANIMATIONS in ADOBE AFTER EFFECTS
2 EASY Line ANIMATIONS in ADOBE AFTER EFFECTS | GLOWING LINES Blotter Media Style Tutorial. 162K views · 3 years ago ...more ...
Read more >
3 ways to keep animation drawings consistent, including Shift ...
This video shows 3 techniques to copy a drawing to keep its size consistent. The first 2 can be used with any software,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found