Description
Noticed this a while ago (while implementing mplcairo) but prompted to report due to #9829:
from matplotlib import pyplot as plt, ticker
fig, axs = plt.subplots(4, 4)
for i, ax in enumerate(axs.flat):
ax.xaxis.set_major_locator(ticker.NullLocator())
ax.yaxis.set_major_locator(ticker.NullLocator())
ax.plot([-1, 0, 1], [0, 1, 0], lw=i, solid_joinstyle="miter")
ax.set(xlim=(-15, 15), ylim=(0, 3))
fig.savefig("/tmp/test.png")
fig.savefig("/tmp/test.svg")
fig.savefig("/tmp/test.pdf")
plt.show()
pdf appears to respect the miter ("pointed") joinstyle (funnily this appears to behave in the opposite manner as #9829):
svg appears to ignore it:
agg changes its mind half-way:
The behavior of agg is almost certainly due to a misunderstanding in how the miter limit is set. See https://www.w3schools.com/tags/canvas_miterlimit.asp and https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-set-miter-limit for the definition of the miter limit. Note that the two definitions differ: html defines it in absolute lengths whereas cairo defines it relative to the linewidth.
backend_agg.h has the line (multiple times)
stroke.miter_limit(points_to_pixels(gc.linewidth));
which suggest that the author thought miter_limit takes an absolute miter limit, but in fact a relative miter limit should have been given (how do I know this? because I can reproduce the same behavior with mplcairo with the same setting, and cairo clearly documents that it uses a relative miter limit :-)).
So the current implementation ends up switching from miter join to bevel join at an angle that depends on the linewidth, eek.
NOTE: when this is fixed, remember to regen the logo per #14939 (which also showcases the issue).