Home > Blockchain >  TypeError: a bytes-like object is required, not 'list' when using pyimgui.plot_lines()
TypeError: a bytes-like object is required, not 'list' when using pyimgui.plot_lines()

Time:01-09

Here is my code:

import imgui
foo = [0.9, 1.1, 1.3, 2.5]

imgui.begin()
imgui.plot_lines("Plot", foo)
imgui.end()

And it gives me this error:

File "imgui\core.pyx", line 6042, in imgui.core.plot_lines
  File "stringsource", line 660, in View.MemoryView.memoryview_cwrapper
  File "stringsource", line 350, in View.MemoryView.memoryview.__cinit__
TypeError: a bytes-like object is required, not 'list'

I tried converting foo to a np.array or to a array.array by doing imgui.plot_lines("Plot", np.array(foo) or array.array(foo) but it didn't work, I was expecting a plot to appear in my window.

CodePudding user response:

The signature of plot_lines is:

def plot_lines(
        str label not None,
        const float[:] values not None,
        int values_count  = -1,
        int values_offset = 0,
        str overlay_text = None,
        float scale_min = FLT_MAX,
        float scale_max = FLT_MAX,
        graph_size = (0, 0),
        int stride = sizeof(float),
    ):

values is a 1D Cython memoryview of type float meaning that what you pass to it must be an object that supports the buffer protocol with a 32 bit floating point number. Both Numpy arrays and array.array can meet that criteria if the underlying type is set correctly, however np.array(foo) creates an array of 64-bit floating point numbers by default. list fails because it doesn't support the buffer-protocol.

There look to be examples of calling plot_lines in the package: https://github.com/pyimgui/pyimgui/blob/480b4de8ab82adaa2cd310100330b41f40274bcc/doc/examples/plots.py#L21-L40.

They pass an array.array but specify the type as a 32-bit float. In your example this would be:

array.array('f', foo)

Alternatively you could specify the type of a Numpy array with

np.array(foo, dtype=np.float32)

The other thing you'll probably need to do (I haven't tested it myself!) is to actually create a window to draw in. The documentation says

The bare imgui.core module is not able to render anything on its own. The imgui.render() function just passes abstract ImGui drawing commands to your rendering backend. In order to make it work you will first have to initialize the rendering backend of your choice.

The code example for plot_lines that I linked to above looks to use GLFW as the backend.

  • Related