proplot
proplot copied to clipboard
Artefacts in hist2d and hexbin output
When I'm making hist2d or hexbin plots in proplot
, I have an issue where in the hist2d the rectangles arent correctly shaped, specifically it seems the lowest pixel row, and when I use hexbin, some of the hexes appear to be smaller or below other hexes.
Proplot code:
import proplot as pplt
import numpy as np
import matplotlib.pyplot as plt
# Sample data
N = 500
state = np.random.RandomState(51423)
x = state.normal(size=(N,))
y = state.normal(size=(N,))
bins = pplt.arange(-3, 3, 0.25)
fig, axs = pplt.subplots(refaspect=1, width='50mm')
axs[0].hist2d(
x, y, bins, vmin=0, vmax=10,
cmap='Blues',
)
Proplot result:
Zoom of the rectangles:
Matplotlib code:
import numpy as np
import matplotlib.pyplot as plt
# Sample data
N = 500
state = np.random.RandomState(51423)
x = state.normal(size=(N,))
y = state.normal(size=(N,))
bins = np.arange(-3, 3.2, 0.25)
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.hist2d(x, y, bins, cmap='Blues', vmin=0, vmax=10)
Matplotlib result
For the hist2d it isnt too bad, especially with high resolutions (since its appears only to be the lowest pixel line). pdf output has the same effect.
The hexbin looks like this:
Proplot:
...
axs[0].hexbin(
x, y, gridsize=20, vmin=0, vmax=10,
cmap='Blues',
)
Matplotlib:
ax.hexbin(x, y, cmap='Blues', gridsize=20, vmin=0, vmax=10)
Version info:
proplot==0.9.5
matplotlib==3.4.3
Using py39 on windows 11
This is related to the "edgefix" feature that tries to repair an issue where distracting white lines appear in saved vector graphics. See the box at the top of this page of the proplot docs, and see this github repo for examples of the problem.
Adding "edges" to cover those white lines can produce weird results for some types of plots... I try to make the width small enough to avoid this, and it mostly works for pcolor
plots, but I can see how for hexbin
plots it's definitely noticeable. I'll play with decreasing the edge width or disabling edgefix
for hexbin
plots in the next version.
For now you can disable "edgefix" globally using pplt.rc.edgefix = False
, locally using ax.hexbin(..., edgefix=False)
, or choose a different linewidth with e.g. ax.hexbin(..., edgefix=0.1)
.
Just remembered that I chose a default edge width of 0.3
so that it would cover white lines in both bitmap (e.g. PNG) and vector (e.g. PDF) outputs. It looks like smaller line widths will start showing white lines in bitmap outputs (see the examples in that github repo showing linewidths of 0.2
and below).
So, decreasing the default edge width further is not an option. I guess the question is whether we prefer "white lines" or "nubs"... because there's no way to perfectly eliminate both.
Thanks! I did run into the white lines issue before in vector graphics. Very frustrating, nice to see there is a fix.
If I use edgefix=False
for histd2
, my issue is resolved. However, for hexbin
it raises an error, and also globally changing the setting has no effect.
axs[0].hexbin(
x, y, gridsize=20, vmin=0, vmax=10,
cmap='Blues', edgefix=False,
)
Results in:
File ...\site-packages\matplotlib\artist.py", line 1062, in update
raise AttributeError(f"{type(self).__name__!r} object "
AttributeError: 'PolyCollection' object has no property 'edgefix'