Remove use of QPolygonF in non-finite cases
With some experimentation, it was determined that when the QPainterPath is drawn with a QPen that has a thickness greater than 1, the end result is quite broken. Due to us trying to exploit non-advertised behavior we are removing this optimization step.
This commit is contained in:
parent
4264219144
commit
649757eb31
|
@ -1708,9 +1708,7 @@ def arrayToQPath(x, y, connect='all', finiteCheck=True):
|
||||||
# make connect argument contain only str type
|
# make connect argument contain only str type
|
||||||
connect_array, connect = connect, 'array'
|
connect_array, connect = connect, 'array'
|
||||||
|
|
||||||
qt6 = QtVersion.startswith("6")
|
use_qpolygonf = connect == 'all'
|
||||||
|
|
||||||
use_qpolygonf = connect == 'all' or (qt6 and connect in ['pairs', 'finite'])
|
|
||||||
|
|
||||||
if use_qpolygonf:
|
if use_qpolygonf:
|
||||||
backstore = create_qpolygonf(n)
|
backstore = create_qpolygonf(n)
|
||||||
|
@ -1727,14 +1725,12 @@ def arrayToQPath(x, y, connect='all', finiteCheck=True):
|
||||||
arr['x'] = x
|
arr['x'] = x
|
||||||
arr['y'] = y
|
arr['y'] = y
|
||||||
|
|
||||||
# inf/nans completely prevent the plot from being displayed starting on
|
# the presence of inf/nans result in an empty QPainterPath being generated
|
||||||
# Qt version 5.12.3; these must now be manually cleaned out.
|
# this behavior started in Qt 5.12.3 and was introduced in this commit
|
||||||
|
# https://github.com/qt/qtbase/commit/c04bd30de072793faee5166cff866a4c4e0a9dd7
|
||||||
|
# We therefore replace non-finite values
|
||||||
isfinite = None
|
isfinite = None
|
||||||
qtver = [int(x) for x in QtVersion.split('.')]
|
if finiteCheck:
|
||||||
if connect == 'finite' and qt6:
|
|
||||||
# we must preserve NaN values here
|
|
||||||
pass
|
|
||||||
elif qtver >= [5, 12, 3] and finiteCheck:
|
|
||||||
isfinite = np.isfinite(x) & np.isfinite(y)
|
isfinite = np.isfinite(x) & np.isfinite(y)
|
||||||
if not np.all(isfinite):
|
if not np.all(isfinite):
|
||||||
# credit: Divakar https://stackoverflow.com/a/41191127/643629
|
# credit: Divakar https://stackoverflow.com/a/41191127/643629
|
||||||
|
@ -1753,16 +1749,6 @@ def arrayToQPath(x, y, connect='all', finiteCheck=True):
|
||||||
path.addPolygon(backstore)
|
path.addPolygon(backstore)
|
||||||
return path
|
return path
|
||||||
elif connect == 'pairs':
|
elif connect == 'pairs':
|
||||||
if qt6:
|
|
||||||
if n % 2 == 1:
|
|
||||||
arr = arr[:-1]
|
|
||||||
polygon = create_qpolygonf(n // 2 * 3)
|
|
||||||
dst = ndarray_from_qpolygonf(polygon).reshape((-1, 6)) # x0, y0, x1, y1, nan, nan
|
|
||||||
dst[:, :4] = np.frombuffer(arr, dtype=np.double).reshape((-1, 4)) # x0, y0, x1, y1
|
|
||||||
dst[:, 4:] = np.nan
|
|
||||||
path.addPolygon(polygon)
|
|
||||||
return path
|
|
||||||
else:
|
|
||||||
arr['c'][::2] = 0
|
arr['c'][::2] = 0
|
||||||
arr['c'][1::2] = 1 # connect every 2nd point to every 1st one
|
arr['c'][1::2] = 1 # connect every 2nd point to every 1st one
|
||||||
elif connect == 'finite':
|
elif connect == 'finite':
|
||||||
|
@ -1770,24 +1756,13 @@ def arrayToQPath(x, y, connect='all', finiteCheck=True):
|
||||||
# A point will anyway not connect to an invalid point regardless of the
|
# A point will anyway not connect to an invalid point regardless of the
|
||||||
# 'c' value of the invalid point. Therefore, we should set 'c' to 0 for
|
# 'c' value of the invalid point. Therefore, we should set 'c' to 0 for
|
||||||
# the next point of an invalid point.
|
# the next point of an invalid point.
|
||||||
if qt6:
|
|
||||||
# look for the first finite element.
|
|
||||||
isfinite = np.isfinite(x) & np.isfinite(y)
|
|
||||||
argNaNs = np.argwhere(isfinite)
|
|
||||||
first = 0 if len(argNaNs) == 0 else argNaNs.item(0)
|
|
||||||
|
|
||||||
# if found, set first element to first found finite element
|
|
||||||
arr[0] = arr[first]
|
|
||||||
path.addPolygon(backstore)
|
|
||||||
return path
|
|
||||||
else:
|
|
||||||
if isfinite is None:
|
if isfinite is None:
|
||||||
isfinite = np.isfinite(x) & np.isfinite(y)
|
isfinite = np.isfinite(x) & np.isfinite(y)
|
||||||
arr[1:]['c'] = isfinite[:-1]
|
arr[1:]['c'] = isfinite[:-1]
|
||||||
elif connect == 'array':
|
elif connect == 'array':
|
||||||
arr[1:]['c'] = connect_array[:-1]
|
arr[1:]['c'] = connect_array[:-1]
|
||||||
else:
|
else:
|
||||||
raise Exception('connect argument must be "all", "pairs", "finite", or array')
|
raise ValueError('connect argument must be "all", "pairs", "finite", or array')
|
||||||
|
|
||||||
arr[0]['c'] = 0 # the first vertex has no previous vertex to connect
|
arr[0]['c'] = 0 # the first vertex has no previous vertex to connect
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,6 @@ def test_siParse(s, suffix, expected):
|
||||||
pg.siParse(s, suffix=suffix)
|
pg.siParse(s, suffix=suffix)
|
||||||
|
|
||||||
|
|
||||||
qt6 = pg.Qt.QtVersion.startswith("6")
|
|
||||||
MoveToElement = pg.QtGui.QPainterPath.ElementType.MoveToElement
|
MoveToElement = pg.QtGui.QPainterPath.ElementType.MoveToElement
|
||||||
LineToElement = pg.QtGui.QPainterPath.ElementType.LineToElement
|
LineToElement = pg.QtGui.QPainterPath.ElementType.LineToElement
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -268,9 +267,9 @@ LineToElement = pg.QtGui.QPainterPath.ElementType.LineToElement
|
||||||
np.arange(6), np.arange(0, -6, step=-1), 'pairs', (
|
np.arange(6), np.arange(0, -6, step=-1), 'pairs', (
|
||||||
(MoveToElement, 0.0, 0.0),
|
(MoveToElement, 0.0, 0.0),
|
||||||
(LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(LineToElement, np.nan, np.nan) if qt6 else (MoveToElement, 2.0, -2.0),
|
(MoveToElement, 2.0, -2.0),
|
||||||
(LineToElement, 3.0, -3.0),
|
(LineToElement, 3.0, -3.0),
|
||||||
(LineToElement, np.nan, np.nan) if qt6 else (MoveToElement, 4.0, -4.0),
|
(MoveToElement, 4.0, -4.0),
|
||||||
(LineToElement, 5.0, -5.0),
|
(LineToElement, 5.0, -5.0),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -278,16 +277,16 @@ LineToElement = pg.QtGui.QPainterPath.ElementType.LineToElement
|
||||||
np.arange(5), np.arange(0, -5, step=-1), 'pairs', (
|
np.arange(5), np.arange(0, -5, step=-1), 'pairs', (
|
||||||
(MoveToElement, 0.0, 0.0),
|
(MoveToElement, 0.0, 0.0),
|
||||||
(LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(LineToElement, np.nan, np.nan) if qt6 else (MoveToElement, 2.0, -2.0),
|
(MoveToElement, 2.0, -2.0),
|
||||||
(LineToElement, 3.0, -3.0),
|
(LineToElement, 3.0, -3.0),
|
||||||
(LineToElement, np.nan, np.nan) if qt6 else (MoveToElement, 4.0, -4.0)
|
(MoveToElement, 4.0, -4.0)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
np.arange(5), np.array([0, -1, np.NaN, -3, -4]), 'finite', (
|
np.arange(5), np.array([0, -1, np.NaN, -3, -4]), 'finite', (
|
||||||
(MoveToElement, 0.0, 0.0),
|
(MoveToElement, 0.0, 0.0),
|
||||||
(LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(LineToElement, 2.0, np.nan) if qt6 else (LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(MoveToElement, 3.0, -3.0),
|
(MoveToElement, 3.0, -3.0),
|
||||||
(LineToElement, 4.0, -4.0)
|
(LineToElement, 4.0, -4.0)
|
||||||
)
|
)
|
||||||
|
@ -296,7 +295,7 @@ LineToElement = pg.QtGui.QPainterPath.ElementType.LineToElement
|
||||||
np.array([0, 1, np.NaN, 3, 4]), np.arange(0, -5, step=-1), 'finite', (
|
np.array([0, 1, np.NaN, 3, 4]), np.arange(0, -5, step=-1), 'finite', (
|
||||||
(MoveToElement, 0.0, 0.0),
|
(MoveToElement, 0.0, 0.0),
|
||||||
(LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(LineToElement, np.nan, -2.0) if qt6 else (LineToElement, 1.0, -1.0),
|
(LineToElement, 1.0, -1.0),
|
||||||
(MoveToElement, 3.0, -3.0),
|
(MoveToElement, 3.0, -3.0),
|
||||||
(LineToElement, 4.0, -4.0)
|
(LineToElement, 4.0, -4.0)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user