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.

Flickering on Live Plotting with Rich

See original GitHub issue

I tried to modify the example code that was raised in this issue that managed to get plotext working with Rich. This is a fairly minimal script that tries to plot a moving sine curve.

The problem is that it shows a lot of flickering.

I am very new to coding with Python so I’m sure there are things that I’m doing that are not right. Possible issues might be around the def make_plot section, or the section when I initialise the plots, or the final Live section.

from rich.layout import Layout
from rich.live import Live
from rich.ansi import AnsiDecoder
from rich.console import RenderGroup
from rich.jupyter import JupyterMixin
from rich.panel import Panel

from datetime import datetime
from rich.table import Table

from time import sleep
import plotext as plt

import numpy as np

def make_plot(width, height):
    # plt.clf()
    plt.clear_data()
    plt.scatter(yy, marker="x")
    plt.plotsize(width, height)
    plt.title(str(count))
    plt.colorless()
    return plt.build()

class plotextMixin(JupyterMixin):
    def __init__(self):
        self.decoder = AnsiDecoder()
        self.count = count
        
    def __rich_console__(self, console, options):
        self.width = options.max_width or console.width
        self.height = options.height or console.height
        canvas = make_plot(self.width, self.height)
        self.rich_canvas = RenderGroup(*self.decoder.decode(canvas))
        yield self.rich_canvas

def make_layout():
    layout = Layout(name="root")
    layout.split(
        Layout(name="header", size=3),
        Layout(name="main", ratio=1),
    )
    layout["main"].split_row(
        Layout(name="plotext", size=100),
        Layout(name="main_right", size=30),
    )
    return layout

# Clear the plot
plt.clf()

# Initialise he count
count = 0

# Initialise the plots
xx = np.arange(0, 6*np.pi, 0.1)
yy = np.sin(xx)
uu = np.stack((xx,yy), axis=1)

layout = make_layout()
plotext_layout = layout["plotext"]
mix = plotextMixin()
mix = Panel(mix, style="white on black")
plotext_layout.update(mix)

header_layout = layout["header"]

with Live(layout, refresh_per_second=0.1) as live:
    while True:
        xx = xx + 0.1*count
        yy = np.sin(xx)
        uu = np.stack((xx,yy),axis=1)
        count = count + 1

        plotext_layout.update(mix)

        plt.sleep(0.01)
        plt.show()

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
piccolomocommented, Feb 14, 2022

Hi @ThSGM,

thanks a lot for dropping your feedback! 😃

I have modified your code and it seem to work fine on my machine. I changed colouring, marker and layout but you could tweek it to suite your preferences. Here it is:

from rich.layout import Layout
from rich.live import Live
from rich.ansi import AnsiDecoder
from rich.console import RenderGroup
from rich.jupyter import JupyterMixin
from rich.panel import Panel
from rich.text import Text
import plotext as plt

def make_plot(width, height, phase = 0, title = None):
    plt.clf()
    l, frames = 1000, 30
    x = range(1, l + 1)
    y = plt.sin(1, periods = 2, length = l, phase = 2 * phase  / frames)
    plt.scatter(x, y, marker = "fhd")
    plt.plotsize(width, height)
    plt.xaxis(0, "upper")
    plt.yaxis(0, "right")
    plt.title(title)
    #color = 255
    #plt.canvas_color(color)
    #plt.axes_color(color)
    #plt.cls()
    return plt.build()

class plotextMixin(JupyterMixin):
    def __init__(self, phase = 0, title = None):
        self.decoder = AnsiDecoder()
        self.phase = phase
        self.title = title
        
    def __rich_console__(self, console, options):
        self.width = options.max_width or console.width
        self.height = options.height or console.height
        canvas = make_plot(self.width, self.height, self.phase, self.title)
        self.rich_canvas = RenderGroup(*self.decoder.decode(canvas))
        yield self.rich_canvas

def make_layout():
    layout = Layout(name = "root")
    layout.split(Layout(name = "header", size = 3), Layout(name="main", ratio = 1))
    layout["main"].split_column(
        Layout(name = "static", ratio = 1),
        Layout(name = "dynamic"))
    return layout

layout = make_layout()

header = layout['header']
title = plt.colorize("Pl✺ ", "cyan bold") + plt.colorize("text ", "dim bold") + "integration with " + plt.colorize("rich_", "bold dim")
spaces = (plt.terminal_size()[0] - len(plt.uncolorize(title))) // 2
header.update(Text("\n" + " " * spaces + title))

static = layout["static"]
dynamic = layout["dynamic"]

mixin_static = plotextMixin(title = "Static Plot")
mixin_static_panel = Panel(mixin_static)
static.update(mixin_static_panel)

mixin_dynamic = plotextMixin(title = "Dynamic Plot")
mixin_dynamic_panel = Panel(mixin_dynamic)

with Live(layout, refresh_per_second = 0.0001) as live:
    while True:
        mixin_dynamic.phase += 1
        dynamic.update(mixin_dynamic_panel)
        live.refresh()

which outputs a static and dynamic plot:

Peek 2022-02-14 19-26

What do you think? Does it work for you as well? Feel free to drop your version if you find a better one 😃

All the best, Savino

P.S. Apologies I edited your post by mistake: I have restored later.

1reaction
ThSGMcommented, Feb 18, 2022

Hello @ThSGM, any update?

(Re-sending on the appropriate account; this response predates this one)

Hello! Thank you for all your help. I’ll do a quick reply for now as I’ve been busy with work.

Basically, your alternative code did not seem to help. I tested it on both macOS iTerm2 and Alacritty and it showed significant flickering. The delay is due to the fact that I wanted to test on a Raspberry Pi/Debian system to see if it was due to the terminal.

I have uploaded a video to show here: https://streamable.com/tl3ktr

But then, even if it does work on Linux/Debian, I think the flickering that persists on iTerm2/Alacritty is still a problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Flickering on live plotting with Rich (plotext and matplotlib)
This is a fairly minimal script that tries to plot a moving sine curve. The problem is that it shows a lot of...
Read more >
R Plot Flickers When Updating Lines - Stack Overflow
However, I have that fix in place in my code, and I still see flickering when plotting multiple lines. The black line that...
Read more >
RefreshReport flicker - MSDN - Microsoft
First thing, certainly your application reloads the data and refreshes report very quickly. That's good as per as performance is concerned but ...
Read more >
Live Display — Rich 12.6.0 documentation
You can build custom live displays with the Live class. For a demonstration of a live display, run the following command: python -m...
Read more >
Why does my TV flicker when I turn on or turn off a light ...
Why do some LED lights flicker when they are turned on and off quickly? ... What could be possible causes for live sound...
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