8000 [Bug]: 3D tick label position jitter when rotating the plot view · Issue #29551 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

[Bug]: 3D tick label position jitter when rotating the plot view #29551

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

Open
scottshambaugh opened this issue Jan 30, 2025 · 7 comments
Open

Comments

@scottshambaugh
Copy link
Contributor
scottshambaugh commented Jan 30, 2025

It seems like there is some rounding going on with 3D tick label positions. When rotating the plot, the position of the labels move around a bit. This may be intentional to line up pixel values, or it may be an artifact, but the result is "jittering" that looks bad.

This becomes most noticeable in animations:
https://github.com/scottshambaugh/mpl_stereo/blob/7c20f7123173eed89370ffa4227be85de514b3a3/docs/trefoil_3d_animation.gif

May be related to #13044? Though there aren't 2D rotations happening here afaik.

TODO: check if the axis labels are also affected

@scottshambaugh scottshambaugh changed the title BUG: 3D tick label position jitter when rotating the plot view [Bug]: 3D tick label position jitter when rotating the plot view Jan 30, 2025
@WeatherGod
Copy link
Member

Another possible reason to consider: antialiasing.

@timhoffm
Copy link
Member

I would be surprised if #13044 is related because the offset for a certain text rotation angle (here 0°) is constant.

You could try a polar plot with an animated set_theta_offset() and see whether rotating the tick labels around the polar plot jitters as well.

< 8000 !-- no margin wins, so we check it last and use its value if true. -->

@QuLogic
Copy link
Member
QuLogic commented Jan 31, 2025

I'm pretty sure this isn't anything to do with 3D, and just that text is snapped to pixels:

import matplotlib.pyplot as plt
import matplotlib.animation as manim

fig = plt.figure(figsize=(2, 2))

text = fig.text(0, 0, 'ABC123')
change = 0.001


def update(*args, **kwargs):
    global change
    x, y = text.get_position()
    if not (0 <= x <= 1 and 0 <= y <= 1):
        change *= -1
    text.set_x(x + change)
    text.set_y(y + change)
    return text,


ani = manim.FuncAnimation(fig, update, interval=20, frames=int(2/change),
                          cache_frame_data=False)

ani.save('text.gif')

Image

If you open this GIF in GIMP, you can see that in a few frames nothing happens, and then it shifts by one pixel one way, and then one pixel the other.

@scottshambaugh
Copy link
Contributor Author
scottshambaugh commented Feb 1, 2025

Spent some time digging into it today, and I agree this is a result of the general text rendering pipeline. Some basic edits to remove rounding in the agg backend didn't change anything, so IMO this is related to the glyph -> bitmap conversion and the associated (anti)aliasing. I wonder if there's a better way to draw the text from the vector paths? I'm getting out of my depth though.

@QuLogic
Copy link
Member

I experimented with subpixel positioning:
Image

It's nearly there, but 1 frame out of 5 or so is a pixel out of place, so you still see a bit of jitter if you stare at it closely.

@anntzer
Copy link
Contributor
anntzer commented Feb 1, 2025

mplcairo looks immune to the problem (from a quick look), likely because it directly renders text to the final buffer rather than going through an intermediate one like agg/ft2font does. I don't know how hard it would be to attach agg's target buffer to ft2font to do the same?

@WeatherGod
Copy link
Member
WeatherGod commented Feb 2, 2025 via email

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

5 participants
0