Skip to content

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

Closed

Description

@scottshambaugh

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

Activity

  1. 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[/+] on Jan 30, 2025
  2. WeatherGod commented on Jan 30, 2025

    @WeatherGod
    Member

    Another possible reason to consider: antialiasing.

  3. timhoffm commented on Jan 30, 2025

    @timhoffm
    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.

  4. QuLogic commented on Jan 31, 2025

    @QuLogic
    Member

    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.

  5. scottshambaugh commented on Feb 1, 2025

    @scottshambaugh
    ContributorAuthor

    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.

  6. QuLogic commented on Feb 1, 2025

    @QuLogic
    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.

  7. anntzer commented on Feb 1, 2025

    @anntzer
    Contributor

    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?

  8. WeatherGod commented on Feb 2, 2025

    @WeatherGod
    Member
  9. moved this from Waiting for other PR to In Progress in Font and text overhaulon Jun 5, 2025
  10. anntzer commented on Feb 3, 2026

    @anntzer
    Contributor

    Closed by #30059.

  11. added this to the v3.11.0 milestone on Feb 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions