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

Zero size ticks show up as single pixels in rendered pdf #6294

Closed
henningpohl opened this issue Apr 12, 2016 · 5 comments
Closed

Zero size ticks show up as single pixels in rendered pdf #6294

henningpohl opened this issue Apr 12, 2016 · 5 comments
Milestone

Comments

@henningpohl
Copy link
Contributor

When using the darkgrid seaborn style, no ticks are rendered. However, in the saved pdf single pixels show up at each tick position. This is not the case when saving the figure as png. Here's an example of what I mean:
untitled-1

At first I assumed this is a seaborn bug. But I can replicate the behavior in matplotlib only code as well. A small example would be:

import matplotlib as mpl
import matplotlib.pyplot as plt

style = {
    "figure.facecolor": "white",
    "xtick.direction": "out",
    "ytick.direction": "out",
    "axes.axisbelow": True,
    "grid.linestyle": "-",
    "lines.solid_capstyle": "round",
    "axes.facecolor": "#EAEAF2",
    "axes.edgecolor": "white",
    "axes.linewidth": 0,
    "grid.color": "white",
    "xtick.major.size": 0,
    "ytick.major.size": 0,
    "xtick.minor.size": 0,
    "ytick.minor.size": 0,
}

mpl.rcParams.update(style)

plt.figure()
plt.bar([0.6, 1.6, 2.6], [10, 20, 30])
plt.xticks([1, 2, 3])
plt.xlim(0.5, 3.5)
plt.ylim(0, 35)
plt.savefig('test.pdf', dpi=300)

I'm running seaborn 0.7.0 and matplotlib 1.5.1 in python 3.4.4 from Anaconda 2.3.0 on 64 bit Windows. The backend used is QT4Agg.

It's not a huge problem as those pixels are not very prominent. But it seems to me no tick rendering should take place at all in the 0 length case.

@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Apr 12, 2016
@tacaswell
Copy link
Member

attn @jkseppan

@kjartankg
Copy link
Contributor

I've been trying to reproduce the bug from the example that you gave but haven't been able to. I don't have the exact same setup. I started with the default Ubuntu install of python 2.7, mpl 1.4.2, then moved on to the 1.5.x branch, then python 3.4.3+, mpl 1.4.2 and finally I fetched the official Anaconda Docker container with python3.

This made me wonder if the pdf backend depends one some OS specific lib file but as far as I can tell that is not the case.

Anyways, I wanted to suggest a workaround until this is solved. You can use

ax.tick_params(color='white')

to make the ticks the same color as the background and thus not visible.

@henningpohl
Copy link
Contributor Author

I did some digging and the problem comes from the transformation set for the marker. The ticks use a Line2D with TICKDOWN markers. If the tick size is zero, this just scales the transformation matrix with 0. So a line is still placed at that position, it just has no extent. For some reason this is still rendered as one dot by Adobe Acrobat. Maybe there is some kind of minimum size it expects? So a more basic example that causes that behavior for me is:

import matplotlib.pylab as plt
from matplotlib.lines import Line2D, TICKDOWN

plt.figure()

l = Line2D((0,), (0,), linestyle='None',
    marker=TICKDOWN, markersize=0)

# markersize=0 is the same as:
l._marker._transform.scale(0.0)

plt.gca().add_artist(l)

plt.xlim(-1, 1)
plt.ylim(-1, 1)

plt.savefig('basic.pdf')

So it might well not be a problem of matpotlib, but a bug in my version of Adobe Reader (Adobe Acrobat X version 10.1.16). But I still think no tick should be drawn at all in this case. I noticed I could also set tick1On and tick2On to False, but maybe the draw method of the Tick class could catch zero size ticks and not call the tick1line.draw and tick2line.draw methods at all?

@mdboom
Copy link
Member

mdboom commented Apr 18, 2016

@henningpohl: Your assessment makes sense. Regardless of where the bug lies, I think we have to treat Adobe Acrobat as the "reference implementation" of PDF, since it's their standard. They probably just didn't consider scaling things down to 0, which is kind of a weird thing to do. I think it should be possible to modify matplotlib so it just doesn't emit the ticks at all in this case (as you suggest), just haven't gotten around to it. Feel free to file a PR for that -- it sounds like you've already done most of the reconnaissance work...

@jkseppan
Copy link
Member

In the PDF rendering model, zero-width lines are specified to be drawn at the thinnest width possible on the output device. Because this is different from other backends, I think there is code in the pdf backend to not draw zero-width lines at all.

Fun detail from the PDF specification: "If a subpath is degenerate (consists of a single-point closed path or of two or more points at the same coordinates), the S operator paints it only if round line caps have been specified, producing a filled circle centered at the single point. If butt or projecting square line caps have been specified, S produces no output, because the orientation of the caps would be indeterminate." So apparently this bug was triggered by the "lines.solid_capstyle": "round" setting.

@QuLogic QuLogic modified the milestones: 1.5.2 (Critical bug fix release), 2.0.1 (next bug fix release) Apr 20, 2016
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

6 participants