- avoid extra work when setLabelAngle would have no effect
- fix errors from bad parent transform (usually the displaying widget has not been given a size yet)
* Exposed ability to set pens for handles and hovering for ROIs
* Consistent color format for pen creation
* Exposed ability to set pens for handles and hovering for ROIs
* Consistent color format for pen creation
* Add handleHoverPen arg to ROI and rename Handle arg to hoverPen
Co-authored-by: nmearl <nchlsearl@gmail.com>
* NEW options for LegendItem
* * changed 'drawFrame' into 'frame'
* added **kwargs to plotItem.addLegend
* added (frame=False, colCount=2) in legend example
* more elegant solution for legend.getLabel
* repaired getLabel
ItemSample.item == plotitem
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* Added arrow symbols for the ScatterPlotItem
* Fixed arrows rotation in scatter plots
* Added new symbols to example
Co-authored-by: Miguel Sánchez de León Peque <msdeleonpeque@gmail.com>
Although the documentation used to say that specifying tipAngle would
override headWidth, headWidth was never used. The new behaviour is that
tipAngle will be used, with a default value of 25, unless headWidth is
specified.
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
- Adds doc strings for user-facing methods so they appear in the
documentation.
- Allows PlotItem.addLegend to accept the same arguments as LegendItem
constructor for convenience.
- Fixes a bug for adding a BarGraphItem (which doesn't have an antialias
option) to LegendItem
* Do not wrap PlotView/ImageView
There is no need to wrap PlotView/ImageView into QMainWindow, since
only purpose of the QMainWindow is some default menu toolbar & menu
handling, that is not used by PyQtGraph anyway.
Moreover, every parent-less Qt widget can become window, so this
change just use PlotView/ImageView as windows, removing extra
complexity, eg. method forwarding, self.win property.
Another benefit of this change, it that these windows get initial
dimensions and titles as they were designed in .ui file.
* Properly cleanup on ImageView.close()
We should not close explicitly child widgets or clear scene, otherwise
Qt will deallocate children views, and cause "wrapped C/C++ object of
type ImageItem has been deleted" error next time we call close()
and/or some other methods.
All children, including self.ui.roiPlot, self.ui.graphicsView will be
closed together with its parent, so there is no need to close them
explicitly.
So the purpose of close it to reclaim the memory, but not to make the existing ImageView object dysfunctional.
* Remove references to plot & image windows after close
PyQtGraph images and plots module list variables are currently holding
references to all plots and image windows returned directly from main
module. This does not seem to be documented however, and causes the Qt
windows to be not released from memory, even if user releases all own
references.
This change removes the references from images/plots list once window
is closed, so when there is no other reference, window and all related
memory is reclaimed.
* Change all UI forms title from Form to PyQtGraph
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* changed structure to redefine axis via
plotitem.setAxes
* cleanuup
* remove old axesitems before adding new ones
* DEBUGGED plotitem.setAxes
NEW AxisItem.setOrientation (needed by plotitem.setAxes)
show/hide right axes after .setAxes()
Co-authored-by: Ogi Moore <ognyan.moore@gmail.com>
* Fix duplicate menus in GradientEditorItem
Add call to ev.accept in Tivk.mouseClickEvent to prevent parent menu from opening on a right click of a Tick.
Co-authored-by: Ogi <ognyan.moore@gmail.com>
Add a check in the viewTransformChanged function to only force a rerender when the downsampling factor changed.
Previously simply moving the image around or zooming in/out without changing the downsampling factor would force a complete rerendering of the image, which was very slow with large images. This way, the expensive rerender is only forced if necessary.
* Check and enforce view limits in the setRange function
* Check limits when setting aspectRatio
- This change is required due to moving the limit checking out of the updateViewRange function.
- If the original logic remained, aspect ratio could be lost due to "squshing" the requested view into the viewBox
* Add tests for ViewBox zooming limits and aspect ratio
* - Move test code to proper location and fix instantiation of QApplication
Co-authored-by: Israel Brewster <ijbrewster@alaska.edu>
* Added test_AxisItem by @mliberty1
As found in https://github.com/pyqtgraph/pyqtgraph/pull/917
* test_AxisItem: Fit to current implementation
* DateAxisItem: Fix documentation to zoomLevels
zoomLevels is not intended to be set by the user (see discussion in converstation from
https://github.com/pyqtgraph/pyqtgraph/pull/1154/files#diff-aefdb23660d0963df0dff3a116baded8
). Also, `zoomLevelWidths` does currently not exist.
This commit adapts the documentation to reflect that.
* DateAxisItem: Do not publish ZoomLevel
* DateAxisItem testing: Removed unnecessary monkeypatch fixture
Co-authored-by: 2xB <2xB@users.noreply.github.com>
To set the tick font of `AxisItem`s, there are two options:
`setStyle({"tickFont":...})` and `setTickFont(...)`.
The first option sets `AxisItem.style['tickFont']`, the second
sets `self.tickFont`. Only `self.tickFont` is actually used.
This PR replaces all occurrences of the second variable with the first
variable, so both options work again. Also, documentation from
`setStyle` is copied to `setTickFont`.
Co-authored-by: 2xB <2xB@users.noreply.github.com>
* remote legacy work-around for old numpy errors
* forgot to remove the numpy_fix import
* require numyp >= 1.8.0
* improve performance of updateData PlotCurveItem (saves about 2us per call)
* improve ScatterPlotItem performance
* Add DateAxisItem
* Change style to camelCase
* Fix missing first tick for negative timestamps
* Add ms precision, auto skipping
Auto skipping allows a zoom level to skip ticks automatically if the
maximum number of ticks/pt is exceeded
* fixes suggested by @goetzc
* workaround for negative argument to utcfromtimestamp on windows
* attachToPlotItem method
* default date axis orientation
* Use new DateAxisItem in Plot Customization example
* attachToPlotItem bugfix
* examples of DateAxisItem
* modified description of customPlot example
* added descriptions to the new examples, reformatted their code, included the first one into utils.py
* typo
* Refactored code for setting axis items into new function
Replaces "DateAxisItem.attachToPlotItem"
* Fix string comparison with ==
* Doc: Slightly more text for DateAxisItem, small improvement for PlotItem
* Make PlotWidget.setAxisItems official
* Fix typo in docstring
* renamed an example
* merge bug fix
* Revert "merge bug fix"
This reverts commit 876b5a7cdb.
* Real bug fix
* support for dates upto -1e13..1e13
* Automatically limit DateAxisItem to a range from -1e12 to 1e12 years
Very large years (|y|>1e13) cause infinite loop, and since nobody
needs time 100 times larger than the age of the universe anyways,
this constrains it to 1e12.
Following suggestion by @axil:
https://github.com/pyqtgraph/pyqtgraph/pull/1154#issuecomment-612662168
* Also catch ValueErrors occuring on Linux before OverfloeErrors
While zooming out, before hitting OverflowErrors, utctimestamp
produces ValueErrors (at least on my Linux machine), so they
are also catched.
* Fix: Timestamp 0 corresponds to year 1970
For large years, x axis labels jump by 1970 years if it is not
accounted for timestamp 0 to be equal to year 1970.
* Fix: When zooming into extreme dates, OSError occurs
This commit catches the OSError like the other observed errors
* Disable stepping below years for dates outside *_REGULAR_TIMESTAMP
2 reasons: First: At least on my Linux machine, zooming into
those dates creates infinite loops. Second: Nobody needs
sub-year-precision for those extreme years anyways.
* Adapt zoom level sizes based on current font size and screen resolution
This is somewhat experimental. With this commit, no longer 60 px are
assumed as width for all zoom levels, but the current font and
display resolution are considered to calculate the width of ticks in
each zoom level. See the new function `updateZoomLevels` for
details.
Before calling this function, overridden functions `paint` and
`generateDrawSpecs` provide information over the current display
and font via `self.fontScaleFactor` and `self.fontMetrics`.
* Meaningful error meassage when adding axis to multiple PlotItems
As @axil noted in the DateAxisItem PR, currently users get a
segmentation fault when one tries to add an axis to multiple
PlotItems. This commit adds a meaningful RuntimeError message
for that case.
* setZoomLevelForDensity: Refactoring and calculating optimal spacing on the fly
* DateTimeAxis Fix: 1970 shows when zooming far out
* Refactoring: Make zoomLevels a customizable dict again
* updated the dateaxisitem example
* Fix: Get screen resolution in a way that also works for Qt 4
This is both a simplification in code and an improvement in backwards compatibility with Qt 4.
* DateAxisItem Fix: Also resolve time below 0.5 seconds
* unix line endings in examples
* DateTimeAxis Fix: For years < 1 and > 9999, stepping broke
Stepping was off by 1970 years for years < 1 and > 9999,
resulting in a gap in ticks visible when zooming out. Fixed by
subtracting the usual 1970 years.
* DateTimeAxis Fix: Zooming out too far causes infinite loop
Fixed by setting default limits to +/- 1e10 years. Should still
be enough.
* improved second dateaxisitem example
* 1..9999 years limit
* DateTimeAxis: Use OrderedDict to stay compatible with Python < 3-6
* DateAxisItem: Use font height to determine spacing for vertical axes
* window title
* added dateaxisitem.rst
* updated index.rst
Co-authored-by: Lukas Heiniger <lukas.heiniger@sed.ethz.ch>
Co-authored-by: Lev Maximov <lev.maximov@gmail.com>
Co-authored-by: 2xB <2xB@users.noreply.github.com>
Items added to a `GraphicsLayout` only learn their size information
after the internal `QGraphicsGridLayout` recalculates the layout.
This is happening as a slot in the Qt event queue.
Not having updated geometry bounds directly after adding an item
leads to multiple issues when not executing the Qt event loop
in time (see below). This commit fixes that by always calling
`layout.activate()` after adding items, updating item sizes
directly.
This is a follow-up to PR #1167, where introducing a direct call to
`processEvents` was suspected to be able to cause side effects.
Notifying @j9ac9k and @campagnola, as they were involved in #1167.
Fixes#8Fixes#1136
Fixes a bug where `setPen`, `setBrush` and `setLabelTextColor` would fail because they call `LegendItem.paint` without a pen. They should instead call `LegendItem.update`.
* More customizable and nicer legend.
- Give kwargs for legend frame and background colors instead of hard-coded values.
- Reduce spacing for more compact legend
- Give separate kwarg `labelTextColor`.
- New method to clear all legend items.
- New methods to get and change `offset` relative to the legend's parent.
- Horizontal instead of tilted lines for legend pictures.
* py3k: Remove reduce calls.
* py3k: Remove compatibility sortList function.
Sorting by key has existed since Python 2.4.
* Remove unnecessary sys.path manipulation.
This file doesn't have any __main__ code to run anyway.
* Use context manager
* Always update transform when setting angle of a TextItem
* Add test to check TextItem.setAngle
* Relax test a bit but still check that setAngle has an effect
* Add docstring to setAngle
* Remove unneeded numpy testing function imports
* Fix: Item on ViewBox causes duplicate paint calls
* Assure call of ViewBox.updateMatrix on resizeEvent
* Fix: Disable autorange on "ViewBox.setRange" before updateAutoRange is called
(Called via updateViewRange -> update -> prepareForPaint)
* Warn if visible window is garbage collected
* (Py)Qt does not rely on Python GC
* Only warn if deleted widget has no parents (if it is a standalone window)
* Hide windows when closing
* Only implement GraphicsView.__del__ if it does not prevent circular reference garbage collection
Basically, profiling has pointed me to the fact that a fair bit of code time is spent in `setShadowPen()` (actually, it's in `mkPen()`, which `setShadowPen()` calls), even when no shadow pen is specified.
In my application, I'm calling `pyqtgraph.PlotDataItem.setdata()`, which calls through PlotDataItem->setData, PlotDataItem->updateItems. At some point in the call stack, the default value for `shadowPen` is being inserted into the kwargs, which then causes the specious calling of setShadowPen.
Anyways, if we check if shadowPen is a value other then none, this doesn't happen.
Currently `_updateMaxTextSize ` will increase the current space required for axis labels, if necessary, but not decrease it when the extra space is no longer needed. The proposed change will release no longer needed space again.
Issue #835 shows that comparing `bins`, which may be a numpy array, with a string `'auto'` leads to element-wise comparison, because the `==` operator for numpy arrays is used. With this commit, potential array and string are switched, so the `==` operator for strings is used, which does no element-wise comparison.
Pull request #907 addressed a specific case where a signal was emitted before a state update.
If an application's slot then calls back into the instance, the instance was in an inconsistent
state. This commit audits and fixes similar issues throughout the pyqtgraph library. This
commit fixes several latent issues:
* SignalProxy: flush -> sigDelayed -> signalReceived would have incorrectly resulted in timer.stop().
* ViewBox: resizeEvent -> sigStateChange -> background state
* ViewBox: setRange -> sigStateChange -> autoranging not updated correctly
* ViewBox: updateMatrix -> sigTransformChanged -> any _matrixNeedsUpdate = True -> ignored
* Parameter: Child may have missed state tree messages on insert or received extra on remove
* GraphicsView: updateMatrix -> sigDeviceRangeChanged/sigDeviceTransformChange -> before propagated to locked viewports.
Do not assume that x-values have uniform spacing -- this can cause problems especially with large datasets and non-uniform spacing (e.g., time-dependent readings from an instrument).
Use `np.searchsorted` instead to find the first and last data index in the view range. This only assumes that x-values are in ascending order. This prevents potentially too strong clipping.