Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plotting fails with numpy >= 2.0 #213

Closed
harmsm opened this issue Jul 3, 2024 · 3 comments
Closed

plotting fails with numpy >= 2.0 #213

harmsm opened this issue Jul 3, 2024 · 3 comments

Comments

@harmsm
Copy link
Contributor

harmsm commented Jul 3, 2024

Summary

Graphs do not render when using numpy 2.0 because numpy changed the string representation of scalar values.

To reproduce

If I run the following code on my machine (toyplot 1.0.4-dev, Python 3.12, numpy 2.0, macOS Sonoma):

import numpy
import toyplot
import toyplot.pdf

x = numpy.linspace(0, 10)
y = x ** 2

canvas = toyplot.Canvas(width=300, height=300)
axes = canvas.cartesian()
mark = axes.plot(x, y)

toyplot.pdf.render(canvas,"test.pdf")

I get the following:

...
File ~/miniconda3/lib/python3.12/site-packages/toyplot/reportlab/__init__.py:253, in render.<locals>.render_element(root, element, canvas, styles)
    249                 path.lineTo(
    250                     float(commands.pop(0)), float(commands.pop(0)))
    251             elif command == "M":
    252                 path.moveTo(
--> 253                     float(commands.pop(0)), float(commands.pop(0)))
    254         canvas.drawPath(path)
    255 elif element.tag == "polygon":

ValueError: could not convert string to float: 'np.float64(50.0)'

It's not just a problem with pdf rendering; the plot does not appear in a Jupyter notebook.

Root cause

This occurs because repr(some_numpy_float) now returns "np.float32(float_value)" instead of "float_value". (See here for spec change). Throughout the code base, toyplot calls float(blah) where blah is a string representation of a numpy float. This fails because values like "np.float(3.0)" cannot be interpreted as floats.

At first I thought the numpy-style strings were all arising in toyplot and that I could fix this by converting all repr(value) calls to str(value) calls. This solved some of the problems I observed; however, it looks like at least some of the numpy-style strings are coming from the standard xml library used to generate svg. This likely means toyplot will have to guard against injecting numpy-style strings into rendered output for the foreseeable future.

One solution

I implemented one possible solution. I made two new functions:toyplot.require.as_float and toyplot.require.as_int. These functions are drop-in replacements for float(value) and float(int) that, upon failing a standard coercion, try to convert from a numpy string representation.

@harmsm
Copy link
Contributor Author

harmsm commented Jul 3, 2024

Just submitted PR.

@tshead2
Copy link
Member

tshead2 commented Jul 9, 2024

@harmsm - thanks for bringing this to my attention. I'm going to clean up some build issues, add a build for numpy 2, and accept the PR.

Cheers,
Tim

@harmsm
Copy link
Contributor Author

harmsm commented Jul 9, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants