When using isort, the order of parametertree/__init__.py imports broke many
of the parameter-types imports. This commit modifies the import statement to
not use the imports from __init__.py but import the respective classes from the
the non-__init__ modules
* allow ThreadTrace to save to a file
* make sure we close our output file
* fix the egregious errors in the file
- no mutable default args
- import things before using them
- variable named obj did not exist, but try/except ignored it
* if it's dumb, and it works, it's not dumb
* linux requires a flush; remove commented code
* always close the file handle, even if its stdout
* it may work for us, but just in case, protect with finally
* turns out: lots of things like to use stdout!
Co-authored-by: Luke Campagnola <lukec@alleninstitute.org>
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* make PlotDataItem aware of mapped data
* inf suppression, metadata storage and refactor of data structures
* cleanup, test, and documentation pass
* re-added prepareForPaint, added PlotDataset to sphinx index
* strip more print statements
* indicate (internal) PlotDataset documentation as orphaned to avoid sphinx error
* Do not export PlotDataset
* replacement example
* example comments
* Allows values to be numpy arrays
* Bugfix: Slider now works when limits didn't change during `optsChanged`
* Improved testing + layout of param tree example
* Also fix numpy-like values in list `setValue`
* use proper hex formatting for value
* Fix code warnings
* Avoids use of configfile in parametertree
* Avoid shadowing variable names
* Add explanatory comment to `makeAllParamTypes`
* Allow string options to be 'unset' in file, etc. parameters example
* Bugfix: unintunitive option unsetting for file window title
* don't use lambda in signal connect
* Remove unused import
* fixes#1769
* Automatically set image to ImageView if imageItem is provided.
Added a test for correct initialization of ImageView with imageItem and levelMode.
* Update PlotItem.py
make update decimate to not unhide curves when items added/removed,
while preserving the Max Traces well behaviour
* Update PlotItem.py
fix typo
* Update PlotItem.py
fix: typo with self as argument
* give better name for the function which handles MaxTraces checkstate change
rename it to _handle_max_traces_toggle
* add doc string to updateDecimation
* add test for PlotItem for external curve visibility control
check if hidden curve would stay hidden when adding or removing other items.
* remove additional empty line between methods
There are small typos in:
- doc/source/how_to_use.rst
- doc/source/region_of_interest.rst
- examples/ViewBox.py
- pyqtgraph/flowchart/Node.py
- pyqtgraph/graphicsItems/AxisItem.py
- pyqtgraph/graphicsItems/PColorMeshItem.py
- pyqtgraph/graphicsItems/PlotDataItem.py
- pyqtgraph/graphicsItems/TargetItem.py
- pyqtgraph/graphicsItems/ViewBox/ViewBox.py
- pyqtgraph/widgets/RawImageWidget.py
Fixes:
- Should read `mapped` rather than `maped`.
- Should read `vector` rather than `vetctor`.
- Should read `value` rather than `vaule`.
- Should read `preferable` rather than `preferrable`.
- Should read `output` rather than `ouptut`.
- Should read `information` rather than `inforation`.
- Should read `information` rather than `infomation`.
- Should read `exempt` rather than `excempt`.
- Should read `emphasizing` rather than `emphacizing`.
- Should read `construction` rather than `constrution`.
* Registered parameter types go in their own files
* Moves [int, float] item definitions outside `WidgetParameterItem`
* Moves [int, float] parameter definitions outside `WidgetParameterItem`
* Allow registering ParameterItems for easy parameter defs
* Finalizes moving simple parameters to their own files
* removes accidentally committed file
* Provides class qualnames in rst
* Address docstring build issues
* Address recent review comments
- `registerParameterItemType`:
* added to docs and parametertree.__init__
* Remove unsed PARAM_TYPES global
* Hyperlink to `registerParameterType`
- parameter tree rst:
* Alphabetize entries
* Rebuild RST without fully qualified class name
* Add note at file header that it is auto generated
* Remove spurious space during rst doc creation
* Ensure created/modified files end with newline
* Address CodeQL warnings
* toPlainText also returns str
* `QTreeWidgetItem.text` returns str
* Fixes#1888
* Improve test coverage of arrayToQPath
* Use early exit to solve empty path instead of slice manipulation
* address codeql qualms: Unused import, uneven tuple
* Remove all usage of python2_3.py
Technically these functions were exported at the top level of the library, this removes them without warning... If we want to we can bring them back for there, but I honestly don't think its needed, as we are py3 only now and have been for multiple releases.
This may introduce a number of 'useless cast' or similar but those were always happening anyway
This PR brought to you by sed
* Update varname in hdf example to avoid collision with builtin
* Clean up some leftover comments surrounding imports of compat code
* Unnecessary string casts
* Additional unnecessary casts
* syntax error fix
* more unnecessary casts
* Yet more unnecessary casts
* Many unused import cleanups
Ignored some star imports, some vendored code in colorama, only looked within pyqtgraph the library, not e.g. examples
* SpinBox decimal imported with both import and from import
depending on the implementation, a zero-sized QPolygonF may not
have any underlying buffer allocated and may return a null pointer when
queried for its "data()"
this null pointer is returned to Python as a "None" which breaks code
not expecting it.
Huge thank you to @feketeimre for the initial PR for this feature
Thank you to @pijyoi for re-implementing with no changes needed to
GLViewWidget and supporting QOpenGLWidget vs. QGLWidget.
* feature More parameter item types
Pen: Pops up a dialouge that allows the user to customize a pen. Setting pen value is not working yet.
Progress bar: For indication things.
Slider: Easier way to set values that dont require precision.
Fonts: Picking font types. Next thing could be a Font dialog.
Calendar: For picking dates or intervals
Open/save file/files/directory: Pops up an open/save file/directory dialog to select a file/directory. Filter string and caption can be defined too.
A PenSelectorDialog widget was created for the pen parameter item too.
Also added these parameter items to the example.
* PyQt/Side6 compatibility fixup
* Revisions from intial PR
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialog.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/parametertree/parameterTypes.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/parametertree/parameterTypes.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialog.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Update pyqtgraph/widgets/PenSelectorDialogbox.py
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
Apply suggestions from code review
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
* Bugfix: module instead of class import on param tree example
* Enrich the slider parameter
* Address pijyoi comments on pen style parameter
* Different file picker for easier porting
* Better organization and formatting, minor refactoring
* PyQt6/PySide6 fixup for file dialog
* Minor adjustment to file picker
* Bugfix: for 'None' sigChanged
'None' is explicitly allowed for a WidgetParameterItem's `sigChanged` value. However, this raises an error on a changed value unless the commit's fix is applied
* Calendar works better as sub item
* Fixes bugs in pen parameter's dialog + makes it resizable
* more bugfixes and recommended changes, lets pen serialize its options
* better pen save state
* Fixes file parameter qualms
* Fixes font parameter qualms
* Fixes calendar parameter qualms
* Fixes multiply-defined slider optsChanged
* Fixes pen parameter qualms
* ptree example minor bugfix
* Pen dialog bugfixes
* File dialog bugfixes / mild improvements
* unto ptree save state regression
* file fixup
* Adds parameter descriptions to docstrings
* Improved parameter documentation
* adds 'relativeTo' option for file parameter
* Less abuse of Qt enums during or-operations
* More uniform handling of relative paths
* More cleanup of enum setting
* better name for window title (matches qt name)
* Favor os.path over pathlib
* Exposes 'directory', 'windowTitle' to file parameter
* Fixup and add comparison to parameter tree state restoration
* Exposes "cosmetic" in pen parameter
* Indicate defaults in parameter documentation
* QtEnumParameter works for enums outside QtCore.Qt
* see if altering pytest report fixes ci bug
* Cleanup unused import and redundant `self.widget` assignments
Co-authored-by: Fekete Imre <feketeimre87@gmail.com>
Co-authored-by: ChristophRose <42769515+ChristophRose@users.noreply.github.com>
* Remove the use of pyqtgraph.ptime
With us supporting python3.7+, we have no more need for the ptime module
and can instead safely use perf_counter for everything.
* Address small issues PR turned up
* Reword comment in ImageView
* Added clipItem option to LinearRegionItem
* Added a clipItem option to LinearRegionItem
Handle case when no self.viewBox() is yet available
* Implement LinearRegionItem clipItem
* Undo unnecessary change
* Update clipItem doc
* Fixup docstring formatting
* Cleanup
* Support clearing clipItem via setBounds. Fix initialization bug
* Add tests for LinearRegionItem clipItem
* Better clipItem demo in crosshair example
* Another test to verify claim in docstring
Co-authored-by: Arjun Chennu <arjun.chennu@gmail.com>
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
Co-authored-by: Arjun Chennu <achennu@mpi-bremen.de>
define opts['viewport'] to be in device pixels.
note from the removed comments that there was one place assuming
opts['viewport'] was in device pixels and the other assuming that it was
in device independent pixels.
1) no need to get rect(), which is actually defined as
QRect(0, 0, width(), height())
2) use col-maj data() instead of row-maj copyDataTo()
- glLoadMatrixf() takes col-maj
* draw GradientLegend in ViewBox coordinates
* some cleanup
* do not proceed with dummy values
* correct bar and label order, add some styling options
* remove debugging code
Replace "pyqtgraph" by "PyQtGraph".
Replace the optional libraries list by an "Optional added functionalities" section.
More precise on the role of each optional library.
Add numba in optional library.
* Allows filtering of examples
* For some reason, the ui designer ignored the courier font family so I manually inserted it into the .ui file
* Allows filtering by file content, too
* Respects dark mode (maybe?), fixes policy setting on code layout
* Prevents "run edited code" from showing unless the actual content changes
* Looks like black font is always best against highlight background
* Left test code in commit...
* Fix broken highlighting on PyQt6
* Address #133
* Better highlighting for both dark and light mode
* Minor refactoring/cleanup, uses combo box instead of checkbox
* Combo box below text edit to avoid clipping
Co-authored-by: njessurun <ntjessu@gmail.com>
* separate out mouse events on main plot area
* work in scenepositions so that detection also works in a layout
* added comments/remove debug statements
* un-busy as many times as needed
* lint
* add test to prove cursor behavior
* tentative change in the hopes that all supported qt versions behave properly
* remove unnecessary code
* use contextmanager decorator instead of class
* use full path to WaitCursor
* restore docstring; refactor variable for clarity
* fix docstring whitespace
* break up long lines
* use variable to shorten instead
There seems to be some unintentional side effect when running examples and the
same time. This change breaks up the execution into two separate calls to
pytest in an attempt to bypass whatever issue is being created.
* exposed number of subsamples in auto-level determination
* Removing print statement at @NilsNemitz's request
* make levelSamples count pixels, not pixels * channels
* minimum number of samples can be 2 if we look at pixels anyway
* adjusted minimum levelSamples to 4: Otherwise a 2x2 image downsamples to a single pixel
* extended docstring for level to make the user aware of auto-level subsampling
* subsample towards square array for auto-leveling
* eliminated duplicated code between level downsampling and samples and QuickMinMax method
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* add axis convenient methods and matrix display example
* wrestled wayward space back into docstring
* color map names are case sensitive on Linux
* docstring fix for PlotItem
* protect AxisItem.linkToView from being obscured by DateAxisItem override
* replaced setOrigin method by promoted setPos and setScale
* made tri-state axes switching explicit
* reverted setRect behavior, documentation pass for ImageItem
* minor text adjustment
* implmented some suggested revisions
* fix input parsing for setRect and add tests so that I don't break it again
* don't try to re-add transform after clearing it
* changed example and doc image generators to pg.exec()
* removed commented-out code
* cleaned up transform eqaulity assertion
* restored devoured comment
* restored devoured comment
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.
* Update GLViewWidget.py
Fix the wrong conversion of QVector3D to numpy array.
* new way to fix the conversion error
* Recover prev. version of pixelSize
Co-authored-by: Jaeyoon Jeong <diem389@gmail.com>
Several bugs have snuck through due to being wrapped with printExc,
which would prevent the exception from raising, but printing the trace
to the console. In pytest, this output is not captured at all, and is
invisible unless the -s parameter is added.
This PR changes the print statement to a runtime warning, which pytest
will capture.
The way we called subprocess.Popen, it looks like we didn't close all
the pipes; this PR addresses the warning that pytest generates when
running the examples.
In addition, we toggle the pytest setting to error on any warning
On Windows, pyreadline is emitting a deprecation warning we can ignore.
Furthermore, test_svg was using NamedTemporaryFile in a manner that was
causing permission denied errors, so this commit switches to the use of
pytest friendly temporary files
This file contains two tests, one of which has been skipped forever,
and the second (test_pg_exit) has been a flakey test that does not test
in general, testing a use-case we likely do not see any more. So
therefore I am removing this test from the library.
While this fix prevents an assertion error, the assertion error was
being suppressed; and was only noticeable via pytest -s where the error
was printed to console. Future work should be done to minimize the use
of bare exceptions so these tests do not fail silently
Remove if __name__ == "__main__" bits, replace some == None to is None
checks
Cleanup variety of static code checker issue
Removed missing imports, restructured some logic to make a little
cleaner, fixed a function in test_dockarea, unfortunately broke the test
so now I tell pytest to expect the Exception.
the test_signalproxy.py had a fixture for the QApplication instance,
only problem is at the end of each use of the fixture, it would mark
the application instance for deletion, which is most definitely not what
we want
To reduce complexity, and make it easier to add more images and tests,
the images in the `test-data` repository should be merged with the main
repository. Furthermore, we can remove a lot of the subprocess work in
the image_testing.py file, as we no longer need to have it interact with
git.
The images are not the same. Images were regenerated with Qt6, and now
have proper big and little endian handling thanks to @pijyoi
Second commit is a slightly modified variant of
2e135ab282d6007b34a3854921be54d0e9efb241 authored by @pijyoi
it is to convert qimages to RGBA8888 for testing. Image
files were regenerated images for the big/little handling
Fixed issue with bogus test from test_NonUniformImage and generated a
new image
Since the QPainterPath.addPolygon(QPolygonF) does not filter out the NaN
values, we can insert NaN values to create discontinuities in the Lines,
and thus supporting connect='pairs' functionality
As discussed earlier, the process of QDataStream >> QPainterPath is
quite slow, so this commit makes an improvement on QPainterPath creation
for the case of connect='pairs' by using a naive method of moving the
path and drawing a line on the path. This was the fastest method
identified during testing.
The check for NaN values in arrayToQPath is expensive, this change
attempts to do the check one time, and if no NaN values are present,
an optional flag is passed along telling arrayToQPath that the check
can be skipped
Since QDataStream >> QPainterPath is an expensive operation, we can
construct our QPainterPath from an open polygon instead but only if the
connect='all' mode is present. Future optimizations work can likely
be had with constructing a polygon from each connected segment
* refactor out _ndarray_to_qimage()
* combine levels back with lut
* make use of Grayscale8, RGB888 and Indexed8 QImage formats
Grayscale8 and RGB888 images are those that are ready for display
without further processing.
* add Grayscale16
* apply the efflut early for uint16 mono/rgb, uint8 rgb
* ndarray indexing is faster than np.take
* handle uint16 rgb(a) with no levels same as levels=[0, 65535]
* add support for Format_RGBA64
* fix: support colormaps of shape (h, 1)
* check ImageItem uint8 and uint16 QImage formats
* uint16 mono with rgb lut -> RGBX8888
* got width and height swapped in array dimensions
* set ImageItem as row-major
* no need to form a 1d 32-bit lut for array indexing
you can index (y, x) into a lookup table of shape (nentry, 3) or
(nentry, 4) and get an output of shape (y, x, 3) or (y, x, 4)
* Revert "no need to form a 1d 32-bit lut for array indexing"
This reverts commit 45cf3100de.
* distinguish between levels_lut and colors_lut
this allows uint16 images with user lut to be rendered as
Format_Indexed8
* uint8 (1-chan) images should always combine to efflut
this efflut will then be used for Indexed8 format color table.
previously, we would be taking a performance hit with doing a numpy
lookup with levels_lut.
* adapt benchmarks/makeARGB.py to renderImageItem.py
* restructure uint8 and uint16 codepaths
* normalize 1-chan images to ndim==2 earlier up
* refactor long code into functions
* bug: qimage may not be assigned
* fix: assign to self.qimage only if not None
* for uint16, do rescale rather than do levels_lut lookup
* cases 2,3 are already handled
i.e. no more using lut to do rescale of uint16 image data.
* rescale rgb images by computation, not by memory lookup
* setImage() does not take an output argument
* try to be cupy compatible
use "xp" instead of numpy module
* add numba to benchmarking
* fix: lut_big is dtype uint8 with more than 256 entries
* bug: applying colors_lut needs C-order
* support float with no nans
* fix: variable could be uninitialized
* add float32 format tests
* avoid explicitly forcing to C-contiguous
* cache effective lut only if combination took place
every one of the four branches now does its own return.
this makes it easier to follow.
* fix cupy benchmark : typo in renderQImage
* remove for loop of 1 iteration
* use float32 for floating point benchmark
* superceded by renderImageItem.py
* lint
* benchmark without lut conversion
* put the lut onto the substrate
* fix editor complaints
* handle lack of cupy
* leading underscores imply privacy
Co-authored-by: KIU Shueng Chuan <nixchuan@gmail.com>
this also fixes the assumption that we are on little-endian.
In [18]: qimg = QtGui.QImage(1, 1, QtGui.QImage.Format.Format_RGB32)
In [19]: qimg.fill(QtCore.Qt.GlobalColor.transparent)
In [20]: np.frombuffer(qimg.bits(), dtype=np.uint8)
Out[20]: array([ 0, 0, 0, 255], dtype=uint8)
* added convenience functions to better handle plotting with gradients
* docstring correction, example name correction
* retrying to get documentation format right
* another attempt at cleaning up docs
* Don't hardcode timer type (and docs fixing attempt)
* more docstring re-formatting
* linebreaks in docstrings
* more documentation adjustments
* documentation pass
* some corrections to documentation
* more adjustments to documentation
* again?
* removed some whitespace and redundant blank lines, changed some checks '== None' to 'is None'
* fixed mis-spelling QColor as Qcolor
* Improve HistogramLUTItem docs, a few cosmetic changes
* Initial implementation of horizontally-oriented HistogramLUTItem
- Also adds support in HistogramLUTWidget
- Fixes AxisItem orientation bug for vertical orientation
- Make use of GradientEditorItem orientation (fixes another bug for
vertical orientation)
- Use horizontal orientation in an example for demonstration
* Remove unused HistogramLUTItem option
* A few more minor fixups
* Copy paste bug
* Use f-strings
* Update from review and a couple more minor updates
* Woops
* Add doc for orientation arg
* Add top/bottom orientation to doc. Expand on levelMode doc a bit
* do not cache the cupy so the config option can be set later
* getCupy will always return None if the option is not set
* test of failing behavior
* divorce skip from option; restore option after test
* implement rescale using numba
* workaround to pass test_makeARGB.py
* key on (input, output) manually
* remove minimum version check
* signature needs to be a list of signatures
numba considers it a mistake for single-item non-list but works around
it internally
* add numba test to test_makeARGB.py
* add numba as dependency in CI
* handle properly the case where useNumba was already True
* restore useCupy setting after test
* filter numba nan warning
* don't make changes to test_cupy_makeARGB_...
This change makes use of QPointF methods which perform faster than the python
equivalent methods. Furthermore, some tests are added.
* Set __slots__ to empty tuple for pg.Point
* Make Point.angle() behave as Vector.angle()
Static code checker identified multiple places where a file is opened
but is not necessarily closed. This commit addressed that with the
exception of RemoteGraphicsView.py
In a few places in the library, we are doing the conversion from radians
to degrees just so we can call QTransform.rotate(), but there is a
QTransform.rotateRadians() method which would be more suitable, thus
making it so we do not have to handle the conversions ourselves
python any and all are able to break early the moment they come across a
member of the iterable that meets the condition; but having a list
comprehension nested within breaks that ability to exit early, as the
list comprehension has to finish being constructed first before it can
be evaluated
Various places in the library attempt to check if scalars are finite
via numpy methods, which are intended to be used on numpy arrays. Using
the math module equivalent functions on scalars is significantly faster.
In a few places, I also use numpy methods explicitly (np.all vs. all)
Many places in the library were doing radian to degree conversion
via the manual calculation. Doing timeit benchmarks on my system, I
am able to get a 4x speedup by using math.degrees or math.radians
instead
Significant performance issues have been identified with np.clip
and thus clip_array was created to speed up the operation. In addition
clip_scalar was created to clip a scalar value between two other values
this commit replaces many uses of np.clip from operating on scalars to
using clip_scalar instead
Using numpy methods that are intended for vectorized operations is
substantially slower than using the math module, so when feasible the
math module methods should be used.
* NEW features for HistgramLUTItem
* gradientPosition=('left', 'right')
* only paint if item is visible (is faster)
* link hisogram to other histograms
* fixes to be able to merge
* drop linkHistogram (rgba needs to be better integrated)
* make sure defaults to same as current behavior
* draw connecting lines correctly on each side
* add example use
When running on macOS Big Sur, pyopenGL is unable to find the bindings
Previously this was assumed that it would be fixed in later versions
of Python 3.8, but that has not happened.
* update to working
* cupy tests, too
* doubling up and down
* add more realism to the benchmarks
* name to reflect scale
* use different numbers to mean different numbers
(that sure does sound tautological)
* more sensible: order, error
* thorough check of lots of makeARGB arg combos
* docstring for tool usage
* no print needed
* better error messages
* test makeARGB using cupy, too
* skip without cupy available
* switch from conda to venv
* skip cupy runs when not available
* use endian-proof makeARGB shim in tests
* generate the asv conf to suit the system
* document running asv
* comments for future matrix goals
* put all makeARGB tests together; name for clarity
* subprocess.check_output is standard for all supported pythons
* better handle lack of git version
* use makeARGB shim
* small fixes and improvements
* Fix the `clickable` property of `PlotDataItem`.
Currently if you attempt to set the `clickable` property of a PlotDataItem,
this property is silently ignored. The expected behavior is to set the
`clickable` property of the underlying PlotCurveItem.
* Use setCurvesClickable and curvesClickable instead
* curve is singular
PyQt6 can serialize / deserialize enums and flags w/o us manually
casting them to int.
In PyQt6 6.0, it was okay to pass the already deserialized flag
back to the class constructor.
In PyQt6 6.1, the flags MouseButtons and KeyboardModifiers have
been renamed to MouseButton and KeyboardModifier respectively.
skipping the reconstruction allows it to work on both PyQt6 6.0 and 6.1.
note that this was already done in deserialize_mouse_event()
the "offset" argument passed into rescaleData() is typically an element
of an ndarray, i.e. it comes from the lower bound value of the "levels"
ndarray. as such, arithmetic operations on it can overflow.
this triggers a runtime warning in the test suite.
the workaround is to convert it to a Python (integer) scalar.
* ROI.py, getArrayRegion: Fix return mapped coordinates
The *getArrayRegion* method is defined as returning a tuple of the points
in the selected region and the mapped coordinates if the
*returnMappedCoords* keyword argument is set to True in the parent class
*ROI*.
In the *EllipseROI* class, *getArrayRegion* was overriden, however it
ignores the *returnMappedCoords* keyword argument, leading to unintended
bugs because of the change in interface between the parent class and
the subclass.
This patch fixes the above bug.
If *returnMappedCoords* is set to False, then only *arr* containing the
array region is returned. If *returnMappedCoords* is set to True, a
tuple of the array region and the mapped coordinates is returned.
NB: At the time of this commit, the same bug is present in several classes
extending *ROI*. This commit only fixes the issue for the *EllipseROI* class.
* ROI.py, PolyLineROI.getArrayRegion: Fix return mapped coordinats
The *getArrayRegion* method is defined as returning a tuple of the
points in the selected region and the mapped coordinates if the
*returnMappedCoords* keyword argument is set to True in the parent class
*ROI*.
In the *PolyLineROI* class, *getArrayRegion* was overriden, however it
ignores the *returnMappedCoords* keyword argument, leading to unintended
bugs because of the change in interface between the parent class and the
subclass.
This patch fixes the above bug. If *returnMappedCoords* is set to
False, then only *arr* containing the array region is returned. If
*returnMappedCoords* is set to True, a tuple of the array region and the
mapped coordinates is returned.
* remove merge conflict cruft
* lint
Co-authored-by: Malik Olivier Boussejra <malik@boussejra.com>
* implement rescaleData_blocked
clip limits should be int if data is int
* add test for rescaleData_blocked
* dispatch to different versions depending on numpy or cupy
* make rescaleData() the only entry-point
* Initial implementation of ColorBarItem
* initial commit
* fixed missing indent
* docstring extension and corrections
* Converted example to match others / run as part of tests
* load local color maps instead of importing from colorcet
* clean up window creation code
* horizontal color bar and clean-up
* switched to mkQApp initialization
* cleaned up some comments
random.normal() generates as float64 and gets converted to a smaller
dtype. generating all the needed data in a single call thus uses a lot
more memory than is necessary.
this changes it such that smaller chunks are generated.
data clipping is also changed to be in-place.
the gaussian filtering which gave the video a washed-out look is also
removed. this also contributed to data generation time.
* allowed style updates to once again update the style of curve and scatter plot, added tests
* tests interleave assign and assert to guard against delayed assignment
* > > > now 100% more camels < < <
* Remove warning about existing QApplication
* Remove reference to weave which we do not use
* Do away with opengl warning
* Remove weaveDebug config option
* fix clip_array()
return error for invalid inputs.
use minmax for win32, umath.clip for other platforms
the previous code was penalizing Linux
* force output to be an array
the Example App allows the user to choose a binding and a graphics
system to use to execute an example.
issue 1: setGraphicsSystem is obsolete and the method no longer exists.
thus selecting a graphics system causes an error.
issue 2: the choice of binding to use is passed as an extra command
line argument to be parsed by initExample. this is problematic for
examples that use argparse, such as VideoSpeedTest.py
issue 3: if the user has set PYQTGRAPH_QT_LIB, that takes precedence
over the choice made in the Example App.
this patch fixes the above 3 issues by setting PYQTGRAPH_QT_LIB in
the child process' environment and removing the old parsing of the
command line arguments
Qt5 docs specify differences between QGLWidget and QOpenGLWidget:
"...when invoking paintGL().
QOpenGLWidget sets up the viewport via glViewport().
It does not perform any clearing."
* feature TriangleROI
Added equilateral TriangleROI.
getArrayRegion is not working yet
* show off (and implicitly test) our new TriangleROI
* the PolyLineROI.getArrayRegion can be used by TriangleROI
refactor the actual logic to live on ROI
* refactors for readability
* variable names
* lint
* docstring type and purpose
Co-authored-by: Fekete Imre <feketeimre87@gmail.com>
* Fix ScatterPlotItem performance regression
* Add hover benchmark to ScatterPlotSpeedTest.py
* Removed a performance regression from GraphicsView
* Removed some tests failing due to the last commit
the previous formulation creates an ndarray and then creates an QImage
over it w/o copying. this relies on the QImage thus created being
non-const.
if the QImage was (unintentionally) created as const, the subsequent
QPainter render on the const QImage would trigger a COW. i.e. the
original underlying ndarray wouldn't be updated.
this is only an issue for PyQt bindings where const QImages can be
created.
* Correct id-based keying of scatter plot pixmap cache
Note: naively using the id function results in non-unique keys.
Alternatively, we could serialize the Qt objects and use these in the key. This would provide protection from the user mutating these later, but at a cost to performance.
* Make id attribute private
* Access class variable instead of instance
Multiple tests are executed by pytest with the same Python process.
The QApplication instance is a global object that will be used by
subsequent tests.
The Qt documentation says that the object will only be deleted while
running in an event loop. In addition, the Qt docs also specifically
say that processEvents() does not process DeferredDelete events.
i.e. calling processEvents() in a loop is not equivalent to calling
QApplication.instance().exec_()
the code being removed was committed in 2012.
the reason for the workaround no longer exists.
the reason this code is under scrutiny is because while porting to
PyQt6, calling ev.type() triggered a bug in PyQt6 6.0
The bug that this workaround was for has been fixed in PyQt6 6.0.1.
However our feature test for the bug was faulty and triggers positive
for PyQt6 6.0.1. In other words, we would be needlessly monkey patching
where it wasn't needed.
in PyQt6 6.0.0, QEvent.Type was automatically pickled / unpickled.
in PyQt6 6.0.1, QEvent.Type is now pickled to be an int, so needs to be
recreated back explicitly (like the other bindings)
this change is backwards compatible with PyQt6 6.0.0
triggered only for PyQt binding, Python 3.8, 3.9
there is a mismatch in API:
- QScreen.logicalDotsPerInchX() -> float
- QSvgGenerator.setResolution(int)
* LegendItem: fix spelling mistake
* LegendItem: remove unused curRow variable
* LegendItem: correct calculation of rowCount
Previously, rowCount would never be updated unless setColumnCount()
was called. This fixes that issue.
It also fixes that setColumnCount() rounded down (floored) the
number of rows, instead of providing an accurate number:
e.g. 4 items in 3 columns would yield rowCount=1, when it should be 2
* LegendItem: remove rowCount argument (not implemented)
Logic to actually use the rowCount argument was not implemented.
Users might expect rowCount to limit the number of rows to e.g. 1,
but that is not what the current code does (it only works with limiting
the number of columns).
Thus, we were exposing an unused/misleading parameter to users.
This can and should be reverted if the logic for limiting the number
of rows is added.
* LegendItem: add colCount docs
* test (LegendItem): remove unused curRow variable
* test (LegendItem): check increasing rowCount as add items
* Fixed logic in placement of items in legend with multiple columns
* Actual row count here should be 2, not 3
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* get test_ref_cycles to pass
let objects die without gc.collect()
if you don't have cyclic references, there should be no need to call
gc.collect()
the usage of gc.collect() was causing pytest running with coverage to
crash on Python 3.7 / PySide2 5.12 / {Linux, Windows}.
* remove imports used only by the removed code
- Increase cross-referencing
- Give all built-in parameter and parameter items at least minimal
docstring
- Start improving coverage of the special options available for some
parameters
- Organize the built in parameters reference for easier navigation
* switch to use of QOpenGLWidget in GraphicsView.py
experimental plotting in PlotCurveItem gets broken by this. so we allow
Qt5 users to opt back to using QGLWidget with the enableExperimental
option.
* allow Qt6 users to turn on enableExperimental
to more easily allow users to see the broken-ness.
* drop QGLWidget, use only QOpenGLWidget
* Legend toggle directly on ItemSample
* Add invisible Eye icon
* Include package data and remove username from svg
* Allow svg and png in the setup.py and cleanup sg
* Removes all translate call on the parameter name and moves them into the title instead allowing to decouple visualization from code logic
* Removes all translate calls from the Exporter class property Name and moves the translation logic when setting the QListWidgetItems for the formatList
* Adds missing call to translation function for the export action on GraphicsScene
fix BufferError: cannot close exported pointers exist
for some reason, even though the ctypes object falls out of function
scope, it causes a lingering reference.
in any case, the use of ctypes is no longer necessary.
Don't change temporary files mid-way for Darwin
This fixes the CI issues on Darwin.
close the remote process on app shutdown.
* Trying translate on exporter strings
* Try translate on other misc context menu strings
* First f-string and I screw it up...
* add more translation calls
* set environment variables before starting QApp
* fix-422
* Better support of hidpi
* Fix Typo in App-Name
* Remove fontScaleFactor bits
* Add documenation for hidpi displays
* Fix pg not defined
* set environment variables before starting QApp
* fix-422
* Better support of hidpi
* Fix Typo in App-Name
* Remove fontScaleFactor bits
* Add documenation for hidpi displays
* fix: delete generated designerExample_*.py files
designerExample.py loads designerExample.ui directly
* remove unused examples/utils.py
* add almost all examples in folder
* use mkQApp and don't set style nor palette
not needed for an example and also avoids a PyQt6 6.0 refcount bug in
app.setStyle()
* bold interesting examples
* test_examples.py needs to know about Namespace too
* Revert "remove unused examples/utils.py"
This reverts commit 2eddead459.
* categorize examples lists in utils.py
mouse interactions had previously only been tested on Qt 5.15 and
Qt 6.0, and found to be not working on Qt 5.12.
differences in Qt 5.12 and Qt 5.15 are documented in the comments.
an addition bug found (and fixed) was that right-click was drawing
the pop-up menu away from the mouse position.
skip tests that don't work for Qt6
add Qt6 and remove Qt4 from test_examples.py
update README.md
switch mouse tests to use QPointF
this eliminates all the special casing for different bindings
* Initial asv configuration
* makeARGB benchmarks are working
* Fix array type checking and allow making QImage in greyscale mode
* Performance improvements
* benchmark minor update
* Add CLI args to video speed test for easier / automated benchmarking
* udpate asv conf
* use a buffer-qimage so we can avoid allocing so much
this should improve performance under windows
* Add CLI args to video speed test for easier / automated benchmarking
* use a buffer-qimage so we can avoid allocing so much
this should improve performance under windows
* playing with numba
* oh, mins/maxes in the other order
* maybe put the cupy in here and see what happens
* pre-alloc for gpu and cpu
* handle possibility of not having cupy
* no numba in this branch
* organize imports
* name them after their use, not their expected device
* cupy.take does not support clip mode, so do it explicitly
* add CUDA option to the VideoSpeedTest
* rename private attr xp to _xp
* handle resizes at the last moment
* cupy is less accepting of lists as args
* or somehow range isn't allowed? what histogram is this?
* construct the array with python objects
* get the python value right away
* put LUT into cupy if needed
* docstring about cuda toolkit version
* better handling and display of missing cuda lib
* lint
* import need
* handle switching between cupy and numpy in a single ImageItem
* only use xp when necessary
we can now depend on numpy >= 1.17, which means __array_function__-implementing cupy can
seamlessly pass into numpy functions. the remaining uses of xp are for our functions which
need to allocate new data structures, an operation that has to be substrate-specific.
remove empty_cupy; just check if the import succeeded, instead.
* use an option to control use of cupy
* convert cupy.ceil array to int for easier mathing
* RawImageWidget gets to use the getCupy function now, too
* raise error to calm linters; rename for clarity
* Add Generated Template Files
* document things better
* cruft removal
* warnings to communicate when cupy is expected but somehow broken
* Merge branch 'cupy-rebase' into 'l/imageitem-performance'
Abundant conflicts; accept theirs in nearly every case.
* playing with settings to suss out timeout
* playing with more stuff to suss out timeout
* replace with empty list
* skip test_ExampleApp on linux+pyside2 only
* clean out some bits that no longer make sense; linty
* ignore airspeed velocity dir
* lint
* tidy up for merge
* lint
* lint, avoid shadowing
* specific import; run-as-script setup
Co-authored-by: Luke Campagnola <luke.campagnola@gmail.com>
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* Add NonUniformImage, example and tests.
* Use updated test-data tag
* Fix line ending, remove lut.setLevels keyword arguments call
Co-authored-by: Ogi <ognyan.moore@gmail.com>
* Add CLI args to video speed test for easier / automated benchmarking
* use a buffer-qimage so we can avoid allocing so much
this should improve performance under windows
* playing with numba
* oh, mins/maxes in the other order
* maybe put the cupy in here and see what happens
* pre-alloc for gpu and cpu
* handle possibility of not having cupy
* no numba in this branch
* organize imports
* name them after their use, not their expected device
* cupy.take does not support clip mode, so do it explicitly
* add CUDA option to the VideoSpeedTest
* rename private attr xp to _xp
* handle resizes at the last moment
* cupy is less accepting of lists as args
* or somehow range isn't allowed? what histogram is this?
* construct the array with python objects
* get the python value right away
* put LUT into cupy if needed
* docstring about cuda toolkit version
* better handling and display of missing cuda lib
* lint
* import need
* handle switching between cupy and numpy in a single ImageItem
* only use xp when necessary
we can now depend on numpy >= 1.17, which means __array_function__-implementing cupy can
seamlessly pass into numpy functions. the remaining uses of xp are for our functions which
need to allocate new data structures, an operation that has to be substrate-specific.
remove empty_cupy; just check if the import succeeded, instead.
* use an option to control use of cupy
* convert cupy.ceil array to int for easier mathing
* RawImageWidget gets to use the getCupy function now, too
* raise error to calm linters; rename for clarity
* Add Generated Template Files
* document things better
* cruft removal
* warnings to communicate when cupy is expected but somehow broken
* playing with settings to suss out timeout
* playing with more stuff to suss out timeout
* replace with empty list
* skip test_ExampleApp on linux+pyside2 only
Co-authored-by: Luke Campagnola <luke.campagnola@gmail.com>
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
from the Qt documentation,
- "AlignCenter = AlignVCenter | AlignHCenter"
- "You can use at most one horizontal and one vertical flag at a time.
Qt::AlignCenter counts as both horizontal and vertical"
- "Conflicting combinations of flags have undefined meanings"
for AxisItem.py, from the code structure, it would appear that the
intent was to use AlignHCenter.
for ROI.py, AlignCenter == AlignCenter | AlignVCenter
test_ImageView()
- PySide6 fails the same as PySide2
test_PlotWidget() and test_GraphicsWindow()
- PySide6 succeeds.
- PySide2 also succeeds. (at least on Linux and on version 5.15.2)
documentation for Qt 4.8 and Qt 5.12 have advised to "Use
AdjustToContents or AdjustToContentsOnFirstShow instead"
documentation in Qt 5.15 no longer shows AdjustToMinimumContentsLength.
Qt5 prototype is QWidget::enterEvent(QEvent*)
Qt6 prototype is QWidget::enterEvent(QEnterEvent*)
where QEnterEvent inherits from QEvent
RemoteGraphicsView.enterEvent() is actually already called with a
QEnterEvent instance, so all we need to do is to be able to reconstruct
it in Renderer.enterEvent()
this lets us support the various bindings w/o having to add binding
specific code.
it breaks PyQt4 support since PyQt4 template files are suffixed as
"_pyqt" rather than "_pyqt4"
QFont.setBold(True) calls QFont.setWeight(QFont.Weight.Bold)
in Qt 5, QFont.Weight.Bold == 75
in Qt 6, QFont.Weight.Bold == 700
in PySide6, QFont.setWeight() no longer accepts an integer value.
convert QTreeWidget.setFirstItemColumnSpanned(item, True) to
item.setFirstColumnSpanned(True)
the former is deprecated since Qt 5.15.2 and removed in Qt 6.
* extend ColorMap functionality for palette management
* manual merge with changes in master branch
* extend ColorMap functionality for palette management
* manual merge with changes in master branch
* light mode / dark mode swapping demo
* color map updates
* added ColorCET and Matplotlib import for color maps
* minor cleanup
* restored lost indent
* Code cleanup
* Add colorcet as optional dependency
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* LegendItem: Introduce itemStyles and provide ToggleItem
Show example
* Minor cleanup of the legend item and test
* Make ItemSample customizable
* Remove example modifications
* Changes for sampleType according to review
* Use log modulus transform for y axis log scaling
* Update log modulus to use eps and retain behaviour around -1 < x < 1
* Update setLogMode Dosctring
* Update setLogMode docString
Co-authored-by: Hanwant <admin@madigan.tech>
* minor adjustment on when test runs
* Remove pytest publish results, add sphinx nitpicky
* Deal with nit-picky mode later
* why bother w/ those artifacts...
* MAINT: Post 0.11.1 release, drop py2, qt4
This focuses on distribution, tests, and docs. This may not be comprehensive, but covers the cases I found by looking and a few greps
Noteably, this does not change any actual internal code yet, to avoid merge conflicts with pending PRs.
* NEP 29 language/versions
This allows you to easily create code to toggle lines on or off by setting to the appropriate array if on, or None if off. Currently you have to have 2 seperate setData calls, one with adj and one without
2020-12-07 17:55:51 -05:00
625 changed files with 41522 additions and 11844 deletions
# This workflows will upload a Python Package using setup.py/twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name:Upload Python Package
on:
release:
types:[created]
jobs:
deploy:
runs-on:ubuntu-latest
steps:
- uses:actions/checkout@v2
- name:Set up Python
uses:actions/setup-python@v2
with:
python-version:'3.x'
- name:Install dependencies
run:|
python -m pip install --upgrade pip
pip install wheel twine setuptools
- name:Build and publish
env:
TWINE_USERNAME:__token__
# The PYPI_PASSWORD must be a pypi token with the "pypi-" prefix with sufficient permissions to upload this package
Contributions to pyqtgraph are welcome! Be kind and respectful! See [our Code of Conduct](CODE_OF_CONDUCT.md) for details.
Please use the following guidelines when preparing changes:
## Submitting Code Changes
## Development Environment Creation
* The preferred method for submitting changes is by github pull request against the "master" branch.
* Pull requests should include only a focused and related set of changes. Mixed features and unrelated changes may be rejected.
* For major changes, it is recommended to discuss your plans on the mailing list or in a github issue before putting in too much effort.
* The following deprecations are being considered by the maintainers
* `pyqtgraph.opengl` may be deprecated and replaced with `VisPy` functionality
* After v0.11, pyqtgraph will adopt [NEP-29](https://numpy.org/neps/nep-0029-deprecation_policy.html) which will effectively mean that python2 support will be deprecated
* Qt4 will be deprecated shortly, as well as Qt5<5.9(andpotentially<5.12)
First thing to do is fork the repository, and clone your own fork to your local computer.
While there is nothing preventing users from using `conda` environments, as a general principle, we recommend using the `venv` module for creating an otherwise empty virtual environment. Furthermore, at this time, WSL is not supported (it can likely be made to work, but you're on your own if you go down this route).
Before making changes to the code-base, create a different branch with a name that should be unique (this makes it easier for maintainers to examine the proposed changes locally).
```bash
git switch -c my-new-feature
```
When you're ready to submit the pull request, do so via the github, and the target of the pull request should be the `master` branch in the pyqtgraph repo.
Pull requests should include only a focused and related set of changes. Mixed features and unrelated changes may be rejected.
For major changes, it is recommended to discuss your plans on the mailing list or in a github issue/discussion before putting in too much effort.
PyQtGraph has adopted [NEP-29](https://numpy.org/neps/nep-0029-deprecation_policy.html) which governs the timeline for phasing out support for numpy and python versions.
## Documentation
* Writing proper documentation and unit tests is highly encouraged. PyQtGraph uses pytest style testing, so tests should usually be included in a tests/ directory adjacent to the relevant code.
* Documentation is generated with sphinx; please check that docstring changes compile correctly
* Writing proper documentation and unit tests is highly encouraged. PyQtGraph uses [`pytest`](https://docs.pytest.org/) for testing.
* Documentation is generated with sphinx, and usage of [numpy-docstyle](https://numpydoc.readthedocs.io/en/latest/format.html) is encouraged (many places in the library do not use this docstring style at present, it's a gradual process to migrate).
* The docs built for this PR can be previewed by clicking on the "Details" link for the read-the-docs entry in the checks section of the PR conversation page.
## Style guidelines
### Rules
### Formatting ~~Rules~~ Suggestions
* PyQtGraph prefers PEP8 for most style issues, but this is not enforced rigorously as long as the code is clean and readable.
* Use `python setup.py style` to see whether your code follows the mandatory style guidelines checked by flake8.
* Exception 1: All variable names should use camelCase rather than underscore_separation. This is done for consistency with Qt
* Exception 2: Function docstrings use ReStructuredText tables for describing arguments:
QObject subclasses that implement new signals should also describe
these in a similar table.
* Variable and Function/Methods that are intended to be part of the public API should be camelCase.
* "Private" methods/variables should have a leading underscore (`_`) before the name.
### Pre-Commit
PyQtGraph developers are highly encouraged to (but not required) to use [`pre-commit`](https://pre-commit.com/). `pre-commit` does a number of checks when attempting to commit the code to ensure it conforms to various standards, such as `flake8`, utf-8 encoding pragma, line-ending fixers, and so on. If any of the checks fail, the commit will be rejected, and you will have the opportunity to make the necessary fixes before adding and committing a file again. This ensures that every commit made conforms to (most) of the styling standards that the library enforces; and you will most likely pass the code style checks by the CI.
PyQtGraph developers are highly encouraged to (but not required) to use [`pre-commit`](https://pre-commit.com/). `pre-commit` does a number of checks when attempting to commit the code to being committed, such as ensuring no large files are accidentally added, address mixed-line-endings types and so on. Check the [pre-commit documentation](https://pre-commit.com) on how to setup.
To make use of `pre-commit`, have it available in your `$PATH` and run `pre-commit install` from the root directory of PyQtGraph.
## Testing
## Testing Setting up a test environment
### Dependencies
### Basic Setup
* tox
* tox-conda
* pytest
* pytest-cov
* pytest-xdist
* Optional: pytest-xvfb
* Optional: pytest-xvfb (used on linux with headless displays)
If you have `pytest<5` (used in python2), you may also want to install `pytest-faulthandler==1.6` plugin to output extra debugging information in case of test failures. This isn't necessary with `pytest>=5`
To run the test suite, after installing the above dependencies run
```bash
python -m pytest examples tests
```
### Tox
As PyQtGraph supports a wide array of Qt-bindings, and python versions, we make use of `tox` to test against most of the configurations in our test matrix. As some of the qt-bindings are only installable via `conda`, `conda` needs to be in your `PATH`, and we utilize the `tox-conda` plugin.
As PyQtGraph supports a wide array of Qt-bindings, and python versions, we make use of `tox` to test against as many supported configurations as feasible. With tox installed, simply run `tox` and it will run through all the configurations. This should be done if there is uncertainty regarding changes working on specific combinations of PyQt bindings and/or python versions.
* Tests for a module should ideally cover all code in that module, i.e., statement coverage should be at 100%.
* To measure the test coverage, un `pytest --cov -n 4` to run the test suite with coverage on 4 cores.
### Continuous Integration
### Continous Integration
For our Continuous Integration, we utilize Github Actions. Tested configurations are visible on [README](README.md).
For our Continuous Integration, we utilize Azure Pipelines. Tested configurations are visible on [README](README.md). More information on coverage and test failures can be found on the respective tabs of the [build results page](https://dev.azure.com/pyqtgraph/pyqtgraph/_build?definitionId=1)
### Benchmarks
( *Still under development* ) To ensure this library is performant, we use [Air Speed Velocity (asv)](https://asv.readthedocs.io/en/stable/) to run benchmarks. For developing on core functions and classes, be aware of any impact your changes have on their speed. To configure and run asv:
The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 18.04, Windows Server 2019, and macOS 10.15 base images.
The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 20.04, Windows Server 2019, and macOS 10.15 base images.
* pyqtgraph has had some incompatibilities with PySide2 versions 5.6-5.11, and we recommend you avoid those versions if possible
* on macOS with Python 2.7 and Qt4 bindings (PyQt4 or PySide) the openGL related visualizations do not work reliably
* :x: - Not compatible
* :white_check_mark: - Tested
Support
-------
* Report issues on the [GitHub issue tracker](https://github.com/pyqtgraph/pyqtgraph/issues)
* Post questions to the [mailing list / forum](https://groups.google.com/forum/?fromgroups#!forum/pyqtgraph) or [StackOverflow](https://stackoverflow.com/questions/tagged/pyqtgraph)
Installation Methods
--------------------
* From PyPI:
* From PyPI:
* Last released version: `pip install pyqtgraph`
* Latest development version: `pip install git+https://github.com/pyqtgraph/pyqtgraph@master`
* From conda
* Last released version: `conda install -c conda-forge pyqtgraph`
* To install system-wide from source distribution: `python setup.py install`
* Many linux package repositories have release versions.
* To use with a specific project, simply copy the pyqtgraph subdirectory
* To use with a specific project, simply copy the PyQtGraph subdirectory
anywhere that is importable from your project.
Documentation
-------------
The official documentation lives at https://pyqtgraph.readthedocs.io
The official documentation lives at [pyqtgraph.readthedocs.io](https://pyqtgraph.readthedocs.io)
The easiest way to learn pyqtgraph is to browse through the examples; run `python -m pyqtgraph.examples` to launch the examples application.
The easiest way to learn PyQtGraph is to browse through the examples; run `python -m pyqtgraph.examples` to launch the examples application.
Used By
-------
Here is a partial listing of some of the applications that make use of PyQtGraph!
@ -30,11 +30,11 @@ Qt uses the classes QColor, QPen, and QBrush to determine how to draw lines and
..autofunction:: pyqtgraph.intColor
..autofunction:: pyqtgraph.colorTuple
..autofunction:: pyqtgraph.CIELabColor
..autofunction:: pyqtgraph.colorStr
..autofunction:: pyqtgraph.colorCIELab
..autofunction:: pyqtgraph.glColor
..autofunction:: pyqtgraph.colorDistance
Data Slicing
@ -65,6 +65,8 @@ SI Unit Conversion Functions
..autofunction:: pyqtgraph.siEval
..autofunction:: pyqtgraph.siParse
Image Preparation Functions
---------------------------
@ -102,3 +104,14 @@ Miscellaneous Functions
..autofunction:: pyqtgraph.exit
Legacy Color Helper Functions
-------------------------------
The following helper functions should no longer be used. The functionality that they implement is trivial and it is suggested that the user use the equivalent QColor methods directly.
@ -51,7 +51,29 @@ For the serious application developer, all of the functionality in pyqtgraph is
#. Under "Header file", enter "pyqtgraph".
#. Click "Add", then click "Promote".
See the designer documentation for more information on promoting widgets. The "VideoSpeedTest" and "ScatterPlotSpeedTest" examples both demonstrate the use of .ui files that are compiled to .py modules using pyuic4 or pyside-uic. The "designerExample" example demonstrates dynamically generating python classes from .ui files (no pyuic4 / pyside-uic needed).
See the designer documentation for more information on promoting widgets. The "VideoSpeedTest" and "ScatterPlotSpeedTest" examples both demonstrate the use of .ui files that are compiled to .py modules using pyuic5 or pyside-uic. The "designerExample" example demonstrates dynamically generating python classes from .ui files (no pyuic5 / pyside-uic needed).
HiDPI Displays
--------------
PyQtGraph has a method :func:`mkQApp <pyqtgraph.Qt.mkQApp>` that by default sets what we have tested to be the best combination of options to support hidpi displays, when in combination with non-hidpi secondary displays. For your application, you may have instantiated ``QApplication`` yourself, in which case we advise setting these options *before* runing ``QApplication.exec_()``.
For Qt6 bindings, this functionally "just works" without having to set any attributes.
On Versions of Qt >= 5.14 and < 6; you can get ideal behavior with the following lines::
@ -61,15 +83,16 @@ PyQtGraph supports two popular python wrappers for the Qt library: PyQt and PySi
APIs and functionality, but for various reasons (discussed elsewhere) you may prefer to use one package or the other. When
pyqtgraph is first imported, it automatically determines which library to use by making the fillowing checks:
#. If PyQt4 is already imported, use that
#. Else, if PySide is already imported, use that
#. Else, attempt to import PyQt4
#. If that import fails, attempt to import PySide.
#. If PyQt5 is already imported, use that
#. Else, if PySide2 is already imported, use that
#. Else, if PySide6 is already imported, use that
#. Else, if PyQt6 is already imported, use that
#. Else, attempt to import PyQt5, PySide2, PySide6, PyQt6, in that order.
If you have both libraries installed on your system and you wish to force pyqtgraph to use one or the other, simply
make sure it is imported before pyqtgraph::
import PySide ## this will force pyqtgraph to use PySide instead of PyQt4
import PySide2 ## this will force pyqtgraph to use PySide2 instead of PyQt5
import pyqtgraph as pg
@ -78,11 +101,11 @@ Embedding PyQtGraph as a sub-package of a larger project
When writing applications or python packages that make use of pyqtgraph, it is most common to install pyqtgraph system-wide (or within a virtualenv) and simply call `import pyqtgraph` from within your application. The main benefit to this is that pyqtgraph is configured independently of your application and thus you (or your users) are free to install newer versions of pyqtgraph without changing anything in your application. This is standard practice when developing with python.
However, it is also often the case, especially for scientific applications, that software is written for a very specific purpose and then archived. If we want to ensure that the software will still work ten years later, then it is preferrable to tie the application to a very specific version of pyqtgraph and *avoid* importing the system-installed version of pyqtgraph, which may be much newer (and potentially incompatible). This is especially the case when the application requires site-specific modifications to the pyqtgraph package which may not be present in the main releases.
Occasionally, a specific program needs to be kept in working order for an extended amount of time after development has been completed. This is often the case for single-purpose scientific applications. If we want to ensure that the software will still work ten years later, then it is preferable to tie it to a very specific version of pyqtgraph and *avoid* importing the system-installed version, which may be much newer and potentially incompatible. This is especially true when the application requires site-specific modifications to the pyqtgraph package.
PyQtGraph facilitates this usage through two mechanisms. First, all internal import statements in pyqtgraph are relative, which allows the package to be renamed or used as a sub-package without any naming conflicts with other versions of pyqtgraph on the system (that is, pyqtgraph never refers to itself internally as 'pyqtgraph'). Second, a git subtree repository is available at https://github.com/pyqtgraph/pyqtgraph-core.git that contains only the 'pyqtgraph/' subtree, allowing the code to be cloned directly as a subtree of the application which uses it.
To support such a separate local installation, all internal import statements in pyqtgraph are relative. That means that pyqtgraph never refers to itself internally as 'pyqtgraph'. This allows the package to be renamed or used as a sub-package without any naming conflicts with other versions of pyqtgraph on the system.
The basic approach is to clone the repository into the appropriate location in your package. When you import pyqtgraph from within your package, be sure to use the full name to avoid importing any system-installed pyqtgraph packages. For example, imagine a simple project has the following structure::
The basic approach is to clone the repository into the appropriate location in your project. When you import pyqtgraph, be sure to use the full name to avoid importing any system-installed pyqtgraph packages. For example, imagine a simple project has the following structure::
my_project/
__init__.py
@ -92,32 +115,32 @@ The basic approach is to clone the repository into the appropriate location in y
def my_plot_function(*data):
pg.plot(*data)
To embed a specific version of pyqtgraph, we would clone the pyqtgraph-core repository inside the project::
To embed a specific version of pyqtgraph, we would clone the pyqtgraph repository inside the project, with a directory name that distinguishes it from a system-wide installation::
import my_project.pyqtgraph as pg # be sure to use the local subpackage
# rather than any globally-installed
# versions.
import local_pyqtgraph.pyqtgraph as pg # be sure to use the local subpackage
# rather than any globally-installed
# version.
def my_plot_function(*data):
pg.plot(*data)
Use ``git checkout pyqtgraph-core-x.x.x`` to select a specific version of the repository, or use ``git pull`` to pull pyqtgraph updates from upstream (see the git documentation for more information).
Use ``git checkout pyqtgraph-x.x.x`` to select a specific library version from the repository, or use ``git pull`` to pull pyqtgraph updates from upstream (see the git documentation for more information). If you do not plan to make use of git's versioning features, adding the option ``--depth 1`` to the ``git clone`` command retrieves only the latest version.
For projects that already use git for code control, it is also possible to include pyqtgraph as a git subtree within your own repository. The major advantage to this approach is that, in addition to being able to pull pyqtgraph updates from the upstream repository, it is also possible to commit your local pyqtgraph changes into the project repository and push those changes upstream::
@ -21,6 +21,6 @@ There are a few other methods for displaying images as well:
* Instances of :class:`~pyqtgraph.ImageItem` can be used inside a :class:`ViewBox <pyqtgraph.ViewBox>` or :class:`GraphicsView <pyqtgraph.GraphicsView>`.
* For higher performance, use :class:`~pyqtgraph.RawImageWidget`.
Any of these classes are acceptable for displaying video by calling setImage() to display a new frame. To increase performance, the image processing system uses scipy.weave to produce compiled libraries. If your computer has a compiler available, weave will automatically attempt to build the libraries it needs on demand. If this fails, then the slower pure-python methods will be used instead.
Any of these classes are acceptable for displaying video by calling setImage() to display a new frame.
For more information, see the classes listed above and the 'VideoSpeedTest', 'ImageItem', 'ImageView', and 'HistogramLUT' :ref:`examples`.
Parameter trees are a system for handling hierarchies of parameters while automatically generating one or more GUIs to display and interact with the parameters.
This feature is commonly seen, for example, in user interface design applications which display a list of editable properties for each widget.
Parameters generally have a name, a data type (int, float, string, color, etc), and a value matching the data type. Parameters may be grouped and nested
to form hierarchies and may be subclassed to provide custom behavior and display widgets.
Parameters generally have a name, a data type (int, float, string, color, etc), and a value matching the data type. Parameters may be grouped and nested to form hierarchies and may be subclassed to provide custom behavior and display widgets.
PyQtGraph's parameter tree system works similarly to the model-view architecture used by some components of Qt: Parameters are purely data-handling classes
that exist independent of any graphical interface. A ParameterTree is a widget that automatically generates a graphical interface which represents
the state of a haierarchy of Parameter objects and allows the user to edit the values within that hierarchy. This separation of data (model) and graphical
interface (view) allows the same data to be represented multiple times and in a variety of different ways.
PyQtGraph's parameter tree system works similarly to the model-view architecture used by some components of Qt:
For more information, see the 'parametertree' example included with pyqtgraph and the API reference
- A :class:`Parameter` is a purely data-handling class that exists independent of any graphical interface.
- A :class:`ParameterItem` is an interactive graphical representation of a :class:`Parameter`.
- A :class:`ParameterTree` is a widget that automatically generates a graphical interface which represents the state of a hierarchy of Parameter objects and allows the user to edit the values within that hierarchy.
This separation of data (model) and graphical interface (view) allows the same data to be represented multiple times and in a variety of different ways.
For example, a floating point number parameter could be represented by a slider or a spinbox, or both.
For more information, see the 'parametertree' example included with pyqtgraph and the API reference:
@ -16,7 +16,7 @@ To select a 2D region from an image, pyqtgraph uses the :class:`ROI <pyqtgraph.R
To automatically extract a region of image data using an ROI and an ImageItem, use :func:`ROI.getArrayRegion <pyqtgraph.ROI.getArrayRegion>`. ROI classes use the :func:`affineSlice <pyqtgraph.affineSlice>` function to perform this extraction.
ROI can also be used as a control for moving/rotating/scaling items in a scene similar to most vetctor graphics editing applications.
ROI can also be used as a control for moving/rotating/scaling items in a scene similar to most vector graphics editing applications.