Fix Small Heights in ErrorBarItem (#1558)

* Add arrayToQPath bit

* No more moveTo or lineTo

* Use better names than 'partial'

* Implement feedback from reviewer
This commit is contained in:
Ogi Moore 2021-02-09 20:42:39 -08:00 committed by GitHub
parent 33365fb730
commit 28e7d4d12c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 23 deletions

View File

@ -662,6 +662,35 @@ def affineSlice(data, shape, origin, vectors, axes, order=1, returnCoords=False,
return output
def interweaveArrays(*args):
"""
Parameters
----------
args : numpy.ndarray
series of 1D numpy arrays of the same length and dtype
Returns
-------
numpy.ndarray
A numpy array with all the input numpy arrays interwoven
Examples
--------
>>> result = interweaveArrays(numpy.ndarray([0, 2, 4]), numpy.ndarray([1, 3, 5]))
>>> result
array([0, 1, 2, 3, 4, 5])
"""
size = sum(x.size for x in args)
result = np.empty((size,), dtype=args[0].dtype)
n = len(args)
for index, array in enumerate(args):
result[index::n] = array
return result
def interpolateArray(data, x, default=0.0, order=1):
"""
N-dimensional interpolation similar to scipy.ndimage.map_coordinates.

View File

@ -2,6 +2,7 @@ from ..Qt import QtGui, QtCore
from .GraphicsObject import GraphicsObject
from .. import getConfigOption
from .. import functions as fn
import numpy as np
__all__ = ['ErrorBarItem']
@ -66,7 +67,6 @@ class ErrorBarItem(GraphicsObject):
beam = self.opts['beam']
height, top, bottom = self.opts['height'], self.opts['top'], self.opts['bottom']
if height is not None or top is not None or bottom is not None:
## draw vertical error bars
@ -82,23 +82,27 @@ class ErrorBarItem(GraphicsObject):
y2 = y
else:
y2 = y + top
for i in range(len(x)):
p.moveTo(x[i], y1[i])
p.lineTo(x[i], y2[i])
xs = fn.interweaveArrays(x, x)
y1_y2 = fn.interweaveArrays(y1, y2)
verticalLines = fn.arrayToQPath(xs, y1_y2, connect="pairs")
p.addPath(verticalLines)
if beam is not None and beam > 0:
x1 = x - beam/2.
x2 = x + beam/2.
x1_x2 = fn.interweaveArrays(x1, x2)
if height is not None or top is not None:
for i in range(len(x)):
p.moveTo(x1[i], y2[i])
p.lineTo(x2[i], y2[i])
y2s = fn.interweaveArrays(y2, y2)
topEnds = fn.arrayToQPath(x1_x2, y2s, connect="pairs")
p.addPath(topEnds)
if height is not None or bottom is not None:
for i in range(len(x)):
p.moveTo(x1[i], y1[i])
p.lineTo(x2[i], y1[i])
y1s = fn.interweaveArrays(y1, y1)
bottomEnds = fn.arrayToQPath(x1_x2, y1s, connect="pairs")
p.addPath(bottomEnds)
width, right, left = self.opts['width'], self.opts['right'], self.opts['left']
if width is not None or right is not None or left is not None:
## draw vertical error bars
@ -115,21 +119,24 @@ class ErrorBarItem(GraphicsObject):
else:
x2 = x + right
for i in range(len(x)):
p.moveTo(x1[i], y[i])
p.lineTo(x2[i], y[i])
ys = fn.interweaveArrays(y, y)
x1_x2 = fn.interweaveArrays(x1, x2)
ends = fn.arrayToQPath(x1_x2, ys, connect='pairs')
p.addPath(ends)
if beam is not None and beam > 0:
y1 = y - beam/2.
y2 = y + beam/2.
y1_y2 = fn.interweaveArrays(y1, y2)
if width is not None or right is not None:
for i in range(len(x)):
p.moveTo(x2[i], y1[i])
p.lineTo(x2[i], y2[i])
x2s = fn.interweaveArrays(x2, x2)
rightEnds = fn.arrayToQPath(x2s, y1_y2, connect="pairs")
p.addPath(rightEnds)
if width is not None or left is not None:
for i in range(len(x)):
p.moveTo(x1[i], y1[i])
p.lineTo(x1[i], y2[i])
x1s = fn.interweaveArrays(x1, x1)
leftEnds = fn.arrayToQPath(x1s, y1_y2, connect="pairs")
p.addPath(leftEnds)
self.path = p
self.prepareGeometryChange()