8000 [Bug]: Mypy not finding the right return type for ax.subplots(...,projection="3d") · Issue #27455 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

[Bug]: Mypy not finding the right return type for ax.subplots(...,projection="3d") #27455

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

Closed
jmdelaney8 opened this issue Dec 6, 2023 · 7 comments

Comments

@jmdelaney8
Copy link

Bug summary

Mypy says that an ax created by ax = fig.add_subplot(..., projection="3d") is type Axes rather than the expected Axes3D. This causes type checking Axes3D methods to fail e.g. ax.plot_surface(). Maybe this is fixed if/when mpl_toolkits gets typing stubs?

Code for reproduction

import numpy as np
from matplotlib import pyplot as plt

# Demo data
x, y = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
z = np.sqrt(x**2 + y**2)

fig = plt.figure()
ax = fig.add_subplot(1, 2, 1, projection="3d")
reveal_type(ax)  # matplotlib.axes._axes.Axes
ax.plot_surface(x, y, z)  # mypy error: "Axes" has no attribute "plot_surface"  [attr-defined]
plt.show()

Actual outcome

python3.9 -m mypy demo.py produces:

demo.py:10: note: Revealed type is "matplotlib.axes._axes.Axes"
demo.py:11: error: "Axes" has no attribute "plot_surface"  [attr-defined]
Found 1 error in 1 file (checked 1 source file)

Expected outcome

Expected no attr-defined mypy error for calling ax.surface() on an Axes3D`

demo.py:10: note: Revealed type is "mpl_toolkits.mplot3d.axes3d.Axes3D"

Additional information

This occurs with the latest mypy (1.7.1)

Operating system

Ubuntu 20.04

Matplotlib Version

3.8.2

Matplotlib Backend

TKAgg

Python version

Python 3.9.5

Jupyter version

No response

Installation

pip

@ksunden
Copy link
Member
ksunden commented Dec 6, 2023

None of the 3d code (or anything else in mpl_toolkits) is type hinted yet, and while we may be able to do the built in projections at least, the projection argument is a very dynamic field which is hard for static type hinting (e.g. you can register your own projections, but there is no way to tell the type checker about them)

In at least the short term, if you know better than the type system, there are cases where you may wish to use typing.cast to inform the type checker.

8000 @jmdelaney8
Copy link
Author

I figured this might be the case, but wanted to flag just to be sure. I appreciate the quick response!

@tacaswell
Copy link
Member

I'm going to close this as "can't fix" as we are pushing the limits of what a static type checker can do on top of our full leveraging of the dynamicness of Python.

@timhoffm
Copy link
8000
Member
timhoffm commented Oct 21, 2024

I you really need to placate static type checkers, you could do

from mpl_toolkits.mplot3d.axes3d import Axes3D
import typing

ax = fig.add_subplot(1, 2, 1, projection="3d")
ax = typing.cast(Axes3D, ax)

@Jeitan
Copy link
Jeitan commented Dec 17, 2024

@timhoffm Is there anything special you did to make that cast work, or a version limitation? I have just tried to do the exact same thing and Mypy is not recognizing the cast at all. Nothing changes in its output whether the cast is there or not. Python 3.11, matplotlib 3.9.3, mypy 1.13.

@QuLogic
Copy link
Member
QuLogic commented Dec 17, 2024

I think the problem is that no toolkits have typing, so casting to an Axes3D does nothing for mypy; it just becomes Any.

@Jeitan
Copy link
Jeitan commented Dec 17, 2024

@QuLogic Ah, that would explain it, thank you! Ugh. I recently upgraded a bunch of versions of things and suddenly I have all these typing errors. I guess I'll just have to turn typing off through the problematic code.

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

No branches or pull requests

7 participants
0