#pyqtgraph
1 messages · Page 3 of 1
I encountered issues with the PySide opengl bindings before
wouldn't surprise me if they're not tested as extensively as pyopengl or moderngl; that said Qt bindings have gotten a lot better over the last ~3-5 years, especially the pyside bindings
For any call where an argument needs to be provided by reference in order to be returned a value, the PySide bindings don't work
(Normally this would be translated by the binding to something that didn't require a pass-in value)
Seems like a major issue if it makes pyside6.OpenGL module outright not work
E.g. glGetIntegerv
glGenBuffers takes in an array to be filled in. Doesn't work either

Any work need doing on this?
hi
hi
Nice to meet you.
Yall gotta add screenshots to this
You’re not wrong. A long-standing goal has been to replicate vispy’s example documentation with code + screenshots
why is bro so stupid
!warn 676960182621962271 calling community members stupid is not in line with our rules and code of conduct
:ok_hand: applied warning to @faint echo.
graph plotting is fun

@fervent vale I don't think I've asked you directly about what you think would be a good way to handle non-linear transformations (log mode more robustly, polar coordinates, and things of that nature)... Luke and Martin started working on coorx ( https://github.com/campagnola/coorx ), which does conversions between coordinate systems via numpy (it handles inverse stuff to get an appropriate number of points/resolution in the coordinate and pixel space).
I'm not convinced that method will work in a way where performance won't be horrifically degraded, I've landed that if we want non-linear transformations, we effectively will have to write our own shaders and use a modern opengl API.
I'd love to hear your take on ways we could go about that.
I don't have a need for non-linear transforms. Or more accurately, it could be something that I didn't know that I needed. Until there's something to try out, people will just "workaround" the fact that there isn't such a feature. So I would wait for coorx to land and check it out.
By the way, the PySide 6.5.3 / 6.6 snapshots both have something that breaks pen parameter's use of signal disconnect.
that's fair, non-linear transformations have been in my opinion the part of the library that is most lacking... but that's true for my projects that made use of pyqtgraph, they haven't really been needed
heya! im new to this but wanna know if u could draw a graph that updates
for example my variable changes every 5 seconds
would i be able to draw the graph live?
There was an example of live plotting in the pyqtgraph repo but I don't seem to be able to find it now. Anyway, apparently there's an addon specifically for it, too: https://github.com/domarm-comat/pglive
@stray parcel you can absolutely have a plot that updates ever X seconds; a number of our examples demonstrate updating plots through the use of QTimer ... in almost all our usages of it, we set the QTimer to have intervals of 0, which is effectively to go off as often as possible for updating; if you want to have a plot update at a fixed time interval, you can adopt one of our examples
here is a file that demonstrates a bunch of the basic plots in pretty short form
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/examples/Plotting.py
you'll notice the timer.start(50), you would need to change that to timer.start(5000) to update every 5 seconds
Oh yup, that's the example - I skipped over it while looking this time, not realising it has a timer in the middle.
the names of our examples are horrifically confusing
our examples need reorganization anyway, we mix in really simple use-cases with more complex use-cases... those need to be decoupled...
the raspberry 5 pi will support opengl es 3.1
https://www.raspberrypi.com/products/raspberry-pi-5/
VideoCore VII GPU, supporting OpenGL ES 3.1, Vulkan 1.2
!compban 487799517496737792
:incoming_envelope: :ok_hand: applied ban to @tulip spindle until <t:1696422060:f> (4 days).
!compban 712504826889764945
:incoming_envelope: :ok_hand: applied ban to @torpid wasp until <t:1696621346:f> (4 days).
idk how this channel is always first target
haha was going to say, if all channels get this amount of activity, you all might be getting overwhelmed 😅
if you'd like to restrict posting to this channel a bit to take the load off of you all, I'd be ok w/ that. Could do something like people w/ pyqtgraph role + mods or something... entirely up to you.
oh no it's not at all a burden. it's just strange how the automated accounts seem to post in #python-discussion and #pyqtgraph
Interesting humble bundle on data visualization: https://www.humblebundle.com/books/data-visualization-taylor-francis-books
This bundle caught my attention as
- it's on a tech but non-usual topic
- it's not using packt publishing books
I'm adding a feature to SpinBox, and I'm wondering what people think. Minimally, I need a scaleAtZero option that lets me set what the default SI prefix should be (which would then apply to whatever number the user might initially type in). This is somewhat related to the way minStep applies, in that a scroll event starting at zero will move up one min-step amount, and implicitly apply the corresponding SI prefix. The main question I have is should minStep behave automatically as scaleAtZero (for when scaleAtZero isn't set)? That seems sensible to me, but it would mean this feature-add is also a behavior-change.
oh, step more generally has the behavior I was describing for minStep, so it should apply there, as well.
i would imagine step is a better place to change behavior than minStep, I haven't worked w/ the spinbox much tho
actually implementing it now, step has variable behavior, depending on whether dec is set or not, so I think maybe only minStep can be used, if at anything.
(step either means whole values to step by, or approximate fractions of the current value to move by)
I also just found a piece of broken code (pyqtgraph.util.garbage_collector calls QTimer.start(float), but only int is accepted), but we never even import this file in the test suite, so it wasn't noticed. anyone want to put money on ACQ4 being the only project that uses this util?
ooo, and a test file that's unused: tests/test_stability.py doesn't have any actual tests, was made by Luke in 2014 and only modified when we've done sweeping global-search-and-replace edits since then.
I'm tempted to add one real test to it: instantiate the GarbageCollector, just so that gets minimally noticed.
I’m curious if that code would even work as intended any more, lots of changes in Python since it was created
By all means patch the qtimer.start call tho
i wonder if mypy would actually catch that at this point, sending a float to QTimer.start() since pyqt/pyside have stubs
oh that's interesting, wonder if it's because they may get uploaded later or if they are outright stopping that effort
looks like the disconnect issue can be resolved by using pyqtgraph.functions::disconnect(signal, slot) so easy enough of a fix, I'll submit a PR
actually using functions::disconnect just catched the exception, no guarantee it actually disconnected... wonder if something else is wrong w/ that signal...
So if it didn't get disconnected, it would then be connected to two slots, which is not the intended behaviour
yeah, using functions.disconnect I don't think is the right answer here...
curious what is so special about this particular signal...
ugh, putting the slot decorator seemed to fix it...probably means we should put those elsewhere in the library too
what was ur previous pr and what excercise are we talking about squat bench or deadlift?
The most related change to the disconnect issue is the fix for PYSIDE-2418
Would really love to know what is so special about that at particular signal/slot. We have so many signals/slots that as far as I can tell we use same exact way…
Suppose first order of business would be to replicate the failure outside of pytest.
The failure occurs for any example using pen parameter
Okay, I have created the MWE:
from PySide6 import QtCore
class Parent(QtCore.QObject):
sig = QtCore.Signal()
def pslot(self):
pass
class Child(Parent):
pass
x = Child()
# disconnecting slot defined in parent fails since PySide >= 6.5.3
x.sig.connect(x.pslot)
x.sig.disconnect(x.pslot)
Nice!
I’ll report the issue
Did you look into any of the books?
I was curious if you have any recommendations in this space, both for my own use but also in the interest of teaching 🙂
I bought the bundle, haven’t had a chance to go through them yet; anything sourcing you have in mind? I’ll be happy to look more closely
I was curious if any of them talk about principles for good data visualization without getting lost in the weeds of any particular library
I want to make a desktop tool that can upload images via api. My input will be a folder and I will get the images in that folder and call the api call and upload them slowly. What if I want it to process asynchronously and not respond when running a long run task?
I using PyQt5.
Not pyqtgraph related, but you can do this, and even bridge python’s asyncio with Qt’s async event loop via the qasync library.
boooooo
@obsidian sapphire I'm going on vacation off the grid for a week, you're in charge of merges 👍
@mortal grotto feel free to merge as well 👍
Whee!
@plush fulcrum looks like when I email a reply to a git discussion it might break the thread? If you can move around discussions feel free to move my posts to the appropriate thread. I’ll try and stick to replying in the GitHub mobile app.
Looks like the signal disconnect issue is resolved for pyside6 6.6.0
The fix is marked "pick to 6.5", so commercial users will get it in 6.5.4 since 6.5 is LTS.
Thanks for the pr pijyoi (on a layover)
and the workaround allows the CI to proceed and fail at optics_demo.py
the conditions there are different. the class is a derived class but the slot in question is not inherited
You think the fix upstream will apply there?
would have to try it out on a 6.6 dev snapshot. but might have to wait a couple of days to be sure that the CI snapshot version includes the fix
If you figure out a pip install command to install the latest snapshot (or series of commands) please post here
I think one of the version parsing constructs in pyqtgraph doesn't work well with things like 6.6.0a1
Almost makes me want to make the packaging library a dependency (already a dependency for pytest)
pip install --no-index --find-links https://download.qt.io/snapshots/ci/pyside/dev/latest/split_wheels/ --force-reinstall PySide6_Essentials
As of now, the snapshot does not include the fix
discord mod can't take a joke...
@fervent vale previously, functions.disconnect typically only returned False if signal wasn't connected to slot .
Do you think it is worth also adding a warning for this Qt version when False is returned that there might indeed be a connection that persisted?
At least from my recent observations, which were mostly with Qt6 bindings, a disconnect of a slot that wasn't connected raises a RuntimeError
Oh I see what you mean
That instead of just returning a False from a caught exception, functions.disconnect should be noisy?
Yes, with a RuntimeWarning or something similar. It would be good to know as a dev since otherwise the exception is silenced by disconnect
Alternatively, if there's some way to get object.receivers() to work, we can check whether the amount decremented by 1 to only warn when there is an actual issue
I don't understand what the pg.reload is supposed to be doing in the except branch
All those code were written in the Qt4 era
So it might be fragile to touch the code there
Right, that code definitely seems vestigial since the blame is ~6 years old
But it might be nice to still get confirmation whether a signal persisted vs. having no signals connected, since the return value is indistinguishable for this Qt release
I see, you want a warning to be raised for PySide 6.5.3 in case anyone was using functions.disconnect?
That is my thought... I think it's worth the additional noise since behavior is undefined in that case
The only user of fn.disconnect seems to be in interactive.py
Why does interactive.py need to use fn.disconnect?
Is it expected that some disconnections will fail?
i.e. in interactive.py::_disconnectParameter, why not just use signal.disconnect(self.runFromChangedOrChanging) instead of fn.disconnect(signal, self.runFromChangedOrChanging)?
The signal is only connected if the user specifies interact(runOptions=RunOptions.ON_CHANG{E,ING}). It uses disconnect to catch and disregard the RuntimeError when that option was not specified and therefore the signal was not connected
would it work to test self.runOptions for RunOptions.ON_CHANG{E,ING} to determine whether a disconnect was necessary?
i.e. avoid using fn.disconnect to swallow exceptions
Currently there is no information stored within InteractiveFunction that specified whether a connection was made. It happens here https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/parametertree/interactive.py#L483
To avoid swallowing the exception, we could incorporate additional bookkeeping during that phase.
As a side note, there are a few repos (acq4 is probably the largest) that make use of pg.disconnect (https://github.com/search?q="pg.disconnect"+language%3Apython&type=code)
Looking at https://github.com/acq4/acq4/tree/main/tools/requirements and https://github.com/search?q=repo%3Aacq4%2Facq4 pyqt6&type=code, I gather that acq4 does not support PySide6 as a backend.
Playing around with tests/parametertree/test_Parameter.py::test_remove_params, I would say that interactive.py's use of disconnect is not affected by PYSIDE-2478. i.e. a connected runFromChangedOrChanging will be successfully disconnected in PySide 6.5.3
If it were up to me, I would just catch the exceptions and avoid the use of fn.disconnect
fn.disconnect calls reload.loadPreviousVersion on failure to disconnect. What sort of side effects is that going to cause?
@fervent vale I haven't tried to use ACQ4 with pyside6 recently, but I know it was variously broken when I tried it right after pyside6 was released, yeah.
hey , basic level pyqtgraph user here
what can i do to not get these kinds of jittering in my realtime plot
self.fetch_timer = QTimer()
self.fetch_timer.timeout.connect(self.fetch_new_data) #gives 20 values every second
self.fetch_timer.start(2000)
self.update_timer = QTimer()
self.update_timer.timeout.connect(self.update_plot) #plots those 20 values to make it look continous and keeps going
self.update_timer.start(100)
To avoid making it jittery you should look at the scrolling plot examples. I think we have plots that scroll smoothly there.
Regarding signal.disconnect I know we had issues with it with pyside2 5.12 conda packages, I think all the supported bindings can be considered stable enough that the regular disconnect methods should work (side-eyeing you pyside6 6.5.3)
Oh okay, thanks I’ll take a look
Back from vacation but going on a work trip… hopefully I’ll have some time to review PRs
!compban 998273668574625873
:incoming_envelope: :ok_hand: applied ban to @high briar until <t:1698596390:f> (4 days).
go away for a few weeks, come back and outstanding PR count is above 40 😂 ...anyway I have a little time, going to try and review/merge/close a few ...
I know this channel is about pyqtgraph but somebody could help me with a trouble I am facing with QSqlRelationalModel and QTableView?
We don’t use either class in our library so probably won’t be of much use here, sorry. Maybe #user-interfaces ?
Generally when looking for usages of objects like that, I have found GitHub’s advanced search to be a very powerful tool.
so many first time contributors! not complaining but it's so odd that in the span of the last month, there have been ~5-ish PRs from 1st time contributors...that's a lot.
effect from hacktober?
perhaps; i didn't do anything specific this year, and the PRs, while simple, address issues that pepole who have used the library would have encountered
https://github.com/pyqtgraph/pyqtgraph/pull/2864
https://github.com/pyqtgraph/pyqtgraph/pull/2869
https://github.com/pyqtgraph/pyqtgraph/pull/2870
there are a few other recent PRs from first time contributors ...so actually we have had more than I thought....
i wanna build a python tool for radio frequancy analysis
how can i do that
is there anyone who can help me
is anyone knows any library which can help me ?
or anyone who have worked on it
also i wanna contribute in python open source projects
is anyone have any suggestion for getting start
Start like any other project. One piece at a time. I would start with rendering a main window with a layout you want, and add bits and pieces one at a time.
<@&831776746206265384> 👆
remove this it is not wanted
Considering this doesn’t appear to use pyqtgraph, this is likely indeed the wrong channel 🙂
@wide prism, Would there be some historical reason that ColorBarItem calls ImageItem::setLookupTable instead of ImageItem::setColorMap?
In the last release, PColorMeshItem added ColorBarItem support but by defining an incompatible setLookupTable that expects QColor
It would seem to me that having ColorBarItem call setColorMap would clean up the PColorMeshItem specific branch.
That PCMI uses QColor luts under the hood should be an implementation detail
I seem to remember that I didn't like
self.setLookupTable( self._colorMap.getLookupTable(nPts=256) )
in setColorMap. This forces the color map to resample at that number of points, rather than using whatever (possibly much smaller) number of points used to actually define the color map.
...
I do not remember if it actually works like that with the current code, but I am pretty sure that was the reason to bypass setColorMap.
In both ImageItem::setColorMap and PColorMeshItem::setColorMap, they will request for 256-pt lut
I was expecting colormap.py to be used to create user-defined color maps from a much smaller number of colors passed manually. For example, look at __initi__ and linearize in colormap.py.
That's probably not really happening, and I have no objections to switching to the 256 points of setColorMap if it cleans things up.
I guess the mindset was that if the color map is actually just 5 interpolated colors, then passing along 256 anchor points for the interpolation isn't really helping.
oh, but that's still working as intended. Even if the Colormap is 5 points, ImageItem and PColorMeshItem will request for 256 resampled points.
I think I might originally have intended to get rid of the resampling to 256 points (or 512, according to getLookupTable's defaults). But the current code indeed does the resampling every time. Then there's probably no reason to bypass setColorMap at all!
Another factor driving the original code is possibly that HistogramLUTItem goes through setLookupTable. ColorBarItem started as a decluttered replacement of that, so the natural starting point was probably to steal the code structure it was using.
Summary: I can see no good reason to deliberately avoid calling ImageItem::setColorMap. If you see a way to clean up the code by using that, go ahead!
I have created #2879 to unify the three image-like items: ImageItem, NonUniformImage, PColorMeshItem
Reading the code, that all looks very good to me! (I have no time to stress test it now, sorry.)
Maybe your testing script should include a manually generated few-color color map, too; But I don't expect any problem there.
Would it be a good idea to expand the test of NonUniformImage to two plots? One with the current black-to-white map, and one with e.g. viridis? That might help catch it if we break something in the color map resampling in the future.
The issue with the NonUniformImage lut and cmap pytests is that they compare against a reference image, and I feel that can be brittle.
Actually the question that comes to me is less of whether a 5-point ColorMap resamples fine to 256-points, but of whether a 256-point ColorMap survives a resampling to 256-points
(1) Makes sense to me.
(2) Maybe create a zebra color map that alternates between black and white each step? Applied to a 256 level image, it should still be all black and white. If anything goes gray, things have gone wrong.
... something in that direction would absolutely be a test we should have 🙂
I need to fix that svg bug I introduced so I can cut a new release… in the coming weeks my time maintaining the library will shrink as I need to get my family’s affairs in order before our move(s)
Which bug would that be?
there isn't an open issue for it (probably a good first step) but it has to do w/ the repositioning of plot items to be between [-1, 1] so that the floating point precision on the SVG output is useful... the issue is I am not moving the plot item back after the SVG is exported. The issue is only apparent with something like log-mode being toggled (no doubt there are other scenarios that will make it apparent as well)
I have really hated that particular "fix" and I had reservations when merging it, in hindsight, I think I could do something more clever w/ QPainter::setWorldTransform
I'll create an issue w/ some example code... but the issue is largely here,
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/exporters/SVGExporter.py#L224-L264
Based on the testing in #2789, svg export was not working at least since 0.12.2 (earlier versions not tested since they don't work with PyQt6 6.5.x)
The changes you made made the svg export work.
Oh I fixed a number of issues, I just introduced a new one is all 🙂
[was looking at https://github.com/pyqtgraph/pyqtgraph/pull/2877/files]
Functionally, the only broken bit is the missing attempt to pass a non-#-prefixed string directly to QColor, right?
On the other hand, I feel a little concerned about firing up the full regular expression machinery just to take apart the hex string - it seems rather dramatic. I mean, that thing is basically a full positronic brain 🙂
Does anyone have an idea if that comes for free, or if it turns out to be noticeable overhead if some code ends up calling mkColor a lot?
Not so long ago I had to parse a lot of fixed format date time strings. It was measurably faster to just crop the digits out at their fixed offsets and to convert them to integer than to call the datetime parser function.
Well, it seems like that parser is already avoiding regex code for the sake of speed:
Lib/_pydatetime.py line 428
# This is equivalent to re.search('[+-Z]', tstr), but faster```
I think I'd prefer mkColor to avoid the regex overhead when its just trying to cut apart hex codes.
before I comment on the PR, would like some timing benchmarks to to better reflect why doing it via regex is something we're not wanting to do
Well, it seems to be less terrible than I thought 🙂
Firing up the regex machine:
python -mtimeit -s "import re" "for c in ['#123', '#abcdefab', 'purple']: match = re.match(r'#([0-9a-fA-F]{3,8})', c)"
200000 loops, best of 5: 1.12 usec per loop
Chopping strings by position:
python -mtimeit -s "import re" "for c in ['#123', '#abcdefab', 'purple']: match = c[1:] if( len(c) in [3,8] and c[0]=='#' ) else ''"
2000000 loops, best of 5: 151 nsec per loop
That's probably not the most fair comparison, but it seems that going to re.match takes about an extra microsecond.
Timing the various QColor construction options might be good, too; but I am out of lunch break now 😁
Hey
I've spent most of the weekend #coding a #python #visualization util/toy in #pyqtgraph
I already disliked #matplotlib, but if you want to add #interactive elements it's essentially hopeless. pyqtgraph is making it a D R E A M
Extending objects, adding callbacks, recomputing elements on subgraphs as I drag points on supergraphs.
And it's so f...
heyhey
!compban 775592170689921054
:incoming_envelope: :ok_hand: applied ban to @sour valve until <t:1702153067:f> (4 days).
<blinks> 49 open PRs?!?!?!
been slacking (getting ready for our move, my household is chaotic right now)... will try and get some of this to a mangable number tonight
7 of them are just automated version bumps
The PyQt6 docs bump to 6.6.1 is needed to avoid failures due to PyQt6 6.6.0 pairing with PyQt6-Qt6 6.6.1
ok i know i just merged the gimmie's ... will try and tackle more of the outstanding ones tomorrow evening
a
завем
Hi, you must speak in English in this server. Thank you.
@timid vapor I've deleted your messages since they're offtopic for this channel. A more apt channel would have been #python-discussion or one of the offtopic channels. If you want a transcript of your messages that I deleted, DM @little pivot .
Hi, I sent a message to the bot. If possible, please follow up. Thanks
who wants to practice matplotlib with me?
this is the wrong channel for this 
sorry i've been quiet folks, getting ready to move across the country, have small kids, it's been a process! should be settled down in my new home in a few weeks
hello guys, when using pyqt and qt threads for serial data collection and processing
what is the best way to also store the data locally?
any inputs are appreciated:) thanks
best way to store data will highly depend on the kind of data it is. PyQtGraph benefits from data being accessible as a numpy array; so however you store the data, I would try and make sure it's "easy" to convert the stored data to a numpy array.
whats pyqtgraph ?
A high performance Python plotting library: https://pyqtgraph.org/
Typically used for scientific applications where user interactivity or rapid plot updating is required, pyqtgraph aims to bridge the gap between NumPy and the Qt GraphicsView framework
wow
this is good
From what I can see, the failures in the CI of PR #2853 for CSVExporter and HDF5Exporter are that they define a list with limits but without a value. And the previous behavior for such a configuration was that the first item in limits would end up being set as the value.
This behavior makes even more sense when you consider that the old allowed name for limits was values.
please have a look people, having a situation with PyQtGraph regarding, displaying real-time chunks of data continuously
https://discord.com/channels/267624335836053506/1200388773981208596
Does the scrolling plots example not cover your use case?
but it is a chunk of data tho, i want the chunk to be plotted sample by samplew ith some delay to make it look continous while when the next chunk comes in the last sample of this chunk is continous wth the firt of the new chuink
thats why i had another datafetcherthread
I thought one of them the subplots in the scrolling plots example showed data coming in at chunks, being appended and the plot scrolling smoothly
pip install —find-links <path> —no-index pyqt5
Going off memory, may be wrong in some of the args, what’s wrong with installing from pypi tho?
Hello bro
Hello bro
huh. I want to plot the path of a robot arm through space (just 2d for now), and I want to represent time as a color gradient. QLinearGradient is what we use for our line colorization, but that's going to give me position-based colors. am I going to have to make a different gradient brush for each line segment?
Hi everyone , i have a question i am having 1.5 experience in pyqt for desktop app development, now i am wondering is this worth working on pyqt, is there any industrial demand?
Probably not the right channel for this. Pyqt is certainly used in some industries. I did interview for a job that used Pyside, but it’s a framework not popular like react or something
looks like I backed up our CI for a while 😅 (most of these merges are small changes)
@fervent vale any PRs you think should be merged before the next release?
There issue #2920
If #2853 is too large, I can make a small PR to fix #2920
it touches a lot of files, but I think it's ok ...
#2877 to remove deprecation warnings
if i have to develop desktop application what technologies will be best suited and also used in most companies.
if you're trying to target "most" companies, learn javascript and then learn to bundle via electron, that's a far more prominent framework than Qt at this point.
ok thanks. i will than try to develop the same software with electron.
will the application made with electron work offline on desktop ?
it would, but if you're working w/ javascript/electron that means you're not using python, so this server probably won't be of much help for you
but i am having 2 years of experience in python. we are developing desktop application but i mostly work on backend very less work experience with frontend pyqt. so should i give a try to electron or should i choose some other thing? help
I cannot help you with your career advice I'm sorry, only thing I can suggest is learn what interests you.
ok
@fervent vale any issue with #2881 ? that one looks safe enough; you mentioned some other changes but they look to be for other parts of that function?
In my opinion, the original unfixed code was trying to be a little too smart. It's trying to clip a 0 difference to the next smallest value
The proposed fix is fixing an unhandled special case
My suggestion was to fix the intention: I.e. avoid a division by zero
When the difference is zero, it's a usage error, so there's no need to try to find the next smallest value
A division by that tiny value would likely just saturate the image anyway
Thanks for the explanation!
I'm triggering a segfault w/ this on macOS
import numpy as np
import scipy
import pyqtgraph as pg
pg.mkQApp()
### create data
x = np.arange(0,500,10)
y = np.random.random(50)*0.3 + scipy.signal.windows.gaussian(50, std=10)
### create plot where export doesn't work because we've increased the x-axis values
p2 = pg.plot()
plot_obj = p2.plot(x=x+10000000, y=y, pen='b')
plot_obj.setLogMode(True, False)
if __name__ == "__main__":
pg.exec()
Run this code, right click on the graph, export to SVG, save, ...shift the view in any direction a little bit, right click and export to SVG again <segfault>
what the hell, why isn't CI running? https://github.com/pyqtgraph/pyqtgraph/pull/2938
EDIT: ok closing/opening did the trick...
huh. I'm getting some weird, intermittent horizontal lines added to my 2D path plot.
add a small test -> conda pyside2 builds segfault....
I really really really really really don't want to support pyside2 anymore, it's ancient all things considered, it hasn't been updated in ages ... at least pyqt5 is getting updates but ... ugh
I'm trying to add a new test, but conda/pyside2 is segfaulting (everything else is passing) so now I'm at the point of uncommenting lines in the test line by line and letting the CI chug at it...
EDIT: seems to be segfaulting when I call plotWidget.scene().showExportDialog() wonder why the CI would crash at that...
EDIT2: at least I can reproduce locally...
EDIT3: no wait... i can't ... what's happening 😵💫
EDIT4: now segfaulting even when I skip the test...
EDIT5: this test seems to be segfaulting?
def test_recreate_from_savestate():
from pyqtgraph.examples import _buildParamTypes
created = _buildParamTypes.makeAllParamTypes()
state = created.saveState()
created2 = pt.Parameter.create(**state)
assert pg.eq(state, created2.saveState())
The test creates a boatload of widgets
#2671 also caused conda CI to crash just by removing an unused WidgetGroup
I still need to clean up my PR but I think I’m just going to skip that test in pyside2
@obsidian sapphire want to look at pijyoi's PR on imageitem autolevels here? https://github.com/pyqtgraph/pyqtgraph/pull/2883
you use imageitem more than I do 👍
I left the PR as draft because I don't think it's adding much value over specifying autoLevels=False each time
Woke up extra early, and finally wrote an issue for the SVG issue that's been bothering me: https://github.com/pyqtgraph/pyqtgraph/issues/2941
Realized i didn’t put in the issue what the original PR was supposed to fix… probably should rewrite the issue accordingly
pijyoi, I think I did a crap job outlining the issue in that bug. I'll try and reword later tonight and include more screenshots
also, there is an easy fix to the issue, remove that if isinstance(item, PlotCurveItem) bit in the SVG exporter code, but that makes #2661 a problem again... but yeah, I need to reword/redo that issue
#2944 segfaults conda by allocating less Qt objects...
what would you think about moving to an arm platform for macOS testing, not sure that would fix the segfault, but a probably better test environment for macOS users. the latest intel platform machine is like 4 years old at this point, so I think migrating to an ARM platform for macOS CI... should be a super easy change in main.yml let me dig it up
macOS arm64 is a separate issue from the conda segfault
i'm pretty exhausted from debugging conda based segfaults and I would support using pytest skipif
it seems to be always conda + pyside2 that has issues. when it happens, it's repeatable. but it's not tied to win, linux, macos.
yeah. I suspect the issue is that pyside2 itself hasn't been updated in ages (by Qt) the updates there are from pyside2-feedstock maintainers... given there are now pyside6 and pyqt6 conda-forge packages, I should migrate the CI to those.
i have an ARM64 mac I can try and see if I can replicate locally if you'd like
https://anaconda.org/conda-forge/pyside6
there is a "modern" pyside6 conda-forge package, for our conda builds I would say we should migrate to those... feel free to ignore the segfault in your PR, or skip the test that you think is triggering it for pyside2 bindings.
(having severe flashbacks to trying to support Qt 5.6 right now)
I suspect it depends on when the garbage collector gets triggered. so randomly removing some test might get it to pass...
that would make sense; wonder if we can tell pytest to run gb.collect() between each test...
https://github.com/pytest-dev/pytest/discussions/8153#discussioncomment-214812
would need to sprinkle that among some tests...
so if I revert the new test back to the old test that instantiates ImageItems, conda passes.
if I switch the conda CI to pyside6, the new test passes
I would just switch to pyside6 then.
maybe we can try #2671 again once we move to conda pyside6
Just a little PSA: heads-up wrt PySide6 6.6.2, if it was upgraded from 6.6.1 some files seems to be missing from the wheel, so the current solution is to re-install. https://bugreports.qt.io/browse/PYSIDE-2616
Thanks for the heads up!!
Got delivery of an RPI5. Stock OS already comes with PyQt5 and PyOpenGL installed. Also was easy to create a virtual environment and install PySide6 since aarch64 wheels are now provided by Qt.
The software sees regular OpenGL, probably partially emulated by MESA. One glitch that I saw in the pyqtgraph OpenGL examples was in the grid and the GLLineItem example. The lines are "stippled"
thanks for testing! that's weird about the lines, curious if the drivers on there have a different default or something...
The "stippled" effect
What version of OpenGL is available via Qt/PyQt?
isOpenGLES: False
VENDOR: Broadcom
RENDERER: V3D 7.1
VERSION: 3.1 Mesa 23.2.1-1~bpo12+rpt3
So antialias needs to be disabled for both GLLineItem and GLGridItem
Ugh was hoping we could use modern open gl
#2939 breaks on arm64
I think OpenGL 3.1 is considered modern (non-legacy) too.
I thought 3.3 was the “modern” variant but I could be remembering wrong
may i ask you why do you keep usino OpenGL?
Name another cross platform graphics acceleration framework that integrates with Qt
Vulkan(?)
Not native to macOS?
Sure it’s available but i still have to distribute it no?
doing release notes for 0.13.4 now, 21 new contributors... holy crap
looking at the auto-generated release notes,...yeah should have done a release a while ago
0.13.4 shipped, thanks everyone for your contributions! 🎊
Been 8 hours, no new issues about this release being broken
I have been using a December snapshot for some time. #2719, #2720, #2726 were particularly important. Allows visualising very long curve plots.
Found a breaking change. Parameter lists no longer accept "values". Must change to "limits".
.
Parameter list limits
Yeah I really should have made a release months ago. Feel free to nag me if you think it’s been too long.
@fervent vale are you still stuck using PyQtGraph on an older system with Qt 5.14?
Minimally, I run Qt 5.15. Anaconda 2023 distro comes bundled with PyQt5 5.15 but with sip 12.11, meaning it doesn't go through the faster array QLineF code path
I couldn't even get PySide6 to run on an air-gapped Ubuntu 22.04 due to xcb-cursor not being installed
Isn’t pyqt6 available on Ubuntu 22.04?
If it is, it's not installed by default
The RPI OS (Debian Bookworm) has PyQt5 installed by default. (PyQt6 6.4.x can be installed using apt)
But the RPI OS uses Wayland on RPI5, so xcb-cursor wasn't needed for PySide6 until I tried using X11
Ahhh
So the requirement for xcb-cursor is actually due to the xcb platform plugin
What is the broader situation of Wayland on Linux? Like is it stable as far as Qt is concerned at this point or are there still edge cases?
Really bummed we don’t have OpenGL 3.3/4.0+ on the RPi5
I only have modest use cases, so wayland seems fine to me. The RPI5 wayland crashes sometimes if I run pytest on pyqtgraph.
The ErrorBarItem test fails more often than not on Wayland ( RPI5 and WSL)
I mean, I don't go out of my way to enable wayland. I use whatever the distro default is.
Fair enough, last time I tried Wayland (like 8 years ago), on a laptop, it was a disaster… running Linux on a laptop that didn’t come with it was already a questionable endeavor … I haven’t used it since (primarily as most of my Linux interaction is via ssh through a text terminal)
Does the rpi5 have OpenGL ES within Qt we could use?
On old versions of RPI OS, Qt was compiled against OpenGL ES. Alternate 64-bit distros like Ubuntu and Arch running on RPI were compiled against OpenGL Desktop. On recent RPI OS Bullseye and Bookworm (64-bits), Qt is compiled against OpenGL Desktop.
So, to answer your question: if you have an RPI5 and running on the stock RPI OS, the only combination is Bookwork 64-bits. Therefore it's only OpenGL Desktop.
To summarize:
RPI3 and RPI4: hardware supports OpenGL Desktop 2.1
RPI5: hardware supports OpenGL Desktop 3.1
So if it is desired to support execution on RPIs, one should stick to 2.1
There seems to be discussion about introducing a QRhiWidget/QRhiWindow to replace QOpenGLWindow ... nice part w/ the QRhiWidget would be that it would use whatever API is native to each platform, and QRhi works w/ OpenGL 2.1+ ... but as it is not rolled out yet ... probably a pipe dream that it will work in python land
too bad we can't get python bindings for something like this: https://github.com/QUItCoding/qnanopainter
Oh
No clue why pyqtgraph/pyqtgraph#2661 is knawing at me so much, but I can't help but feel like I'm sooo close to a solution...
feels like I should be able to apply a QTransform to the various GraphicsItems in the plot, and the view itself to get all the graphics items (temporarily) between [0, 1] while the QSvgGenerator does its things, then move them back... but I haven't been able to get it :/
so I'm tinkering with the docs in your PR pijyoi, and I'm not sure what it should look like: I can do this:
napoleon_type_aliases = {
...
'colormap specifiers': ':class:`str`, (:class:`str`, :class:`str`), :class:`~pyqtgraph.ColorMap`'
}
userList : list of colormap specifiers, optional
Supported colormap specifiers are: ``str``, ``(str, str)``, :class:`~pyqtgraph.ColorMap`.
Example: ``["viridis", ("glasbey", "colorcet"), ("rainbow", "matplotlib")]``
but the rendered output, would look like the attached photo
but not doing anything, and leaving colormap specifiers alone, results in a sphinx build warning
/Users/ogi/Developer/pyqtgraph/pyqtgraph/widgets/ColorMapButton.py:docstring of pyqtgraph.widgets.ColorMapButton.ColorMapMenu.__init__:6: WARNING: py:class reference target not found: colormap specifiers
how would you feel about this? Would need to add some CSS to hide the class declaration tho that is highlighted
Looks great to me
the fact I have to edit css to make these kinds of alias's work is ridiculous 😂
My goodness, the issues are now rolling in!
it's after 24 hours so it doesn't count 😛
I am going to count #2960 as a non-issue
say it's a non-issue here, submit a PR 1 hour later 😛
The issue submitter thought they only had 600 unique symbols, but in fact each of the 200K points was a unique symbol due to non-reuse of brushes
😬
pijyoi, enxt time you're using the Rpi5, can you try starting python with MESA_GL_VERSION_OVERRIDE=3.3 python and see what version of opengl is returned that way? ... might be able to get it via glXGetClientString(GLX_VERSION) or something like that
$ MESA_GL_VERSION_OVERRIDE=3.3 python -m pyqtgraph.util.glinfo | head -4
isOpenGLES: False
VENDOR: Broadcom
RENDERER: V3D 7.1
VERSION: 3.3 (Compatibility Profile) Mesa 23.2.1-1~bpo12+rpt3
related to the qnanopainter that you posted earlier: https://github.com/mitsuba-renderer/nanogui
it can build against GLES 2.0, GLES 3.0, OpenGL 3.2
I got it to run with GLES 2.0 out of the box; GLES 3.0 with some header include fixes; and with the override environment variable, got it to run on OpenGL (RPI5 OpenGL is 3.1)
I'm taking the David Beazley build a compiler course: https://www.dabeaz.com/compiler.html
I got further introduced to the switch/case syntax that got introduced in Python 3.10... I'm soooooo excited to use it
Some of the folks in the ModernGL channel are really confused by the output of glinfo on the rpi, there seems to be a belief that it's lying to us about isOpenGLES
The suggestion there was to start a QOpenGLWidget (or QOpenGLWindow) and then query the version.
from OpenGL.GL import *
print(glGetString(GL_VERSION))
another comment:
you have to get rid of running using the software mesa driver. i had to use raspi config and enable gles there
isOpenGLES reports what the Qt library has been compiled against.
On 32-bit RaspiOS, Qt is compiled against GLES. On 64-bit RaspiOS, Qt is compiled against OpenGL Desktop.
I have an RPI 3B and RPI 5. Quite a bit has changed in terms of the Linux distro and also the graphics drivers over the years.
If I run stuff over ssh, then it becomes software OpenGL (MESA llvmpipe)
If I run stuff over vnc, it's running hardware accelerated
Wonder why that is with the ssh, maybe needs a connected display, and VNC is able to emulate that
There's even a DOOM 3 port that runs on RPI 4 and 5
Apparently it's only using OpenGL 1.4
Anyway, RPI3 gfx chip is different from RPI4 and RPI5 gfx chip
This is the output of glxinfo
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Broadcom (0x14e4)
Device: V3D 7.1 (0xffffffff)
Version: 23.2.1
Accelerated: yes
Video memory: 8052MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 3.1
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
I have an RPI 3B and RPI 5. Quite a bit
cool project
hello all.
@copper lily Hello, I've deleted your message since it's not relevant to this channel. Please read the channel's topic before posting.
interestingly, I am getting bitten by numpy <= 1.22 issues, which should have expired on 2024/01/01
Oh? While I knew we support only 1.23+ I didn’t realize we actually had an incompatibility
Our CI still uses 1.22 as the lowest version. I had a commit that made Py39 + Qt5 runners fail. Took a while to trace it to being Numpy 1.22
Oh oh I misread. Feel free to bump the numpy version in CI in your PR (or wait for me to do it)
Actually I have worked around it. But now on further thought, if we use newer behaviours of numpy, we would also need to verify that cupy behaviour matches
!compban 1027630394994085938
:incoming_envelope: :ok_hand: applied ban to @uneven wing until <t:1712091040:f> (4 days).
I had switched temporarily to numpy 1.22.4 to test out the issue. I had forgotten about the bad np.clip performance on Windows / MSVC that got fixed since 1.25. For the purposes of ImageItem from float data, (Windows x64 laptop, numpy 1.22.4) was running 2x-3x as slow as (RPI5, numpy 1.26.4)
Seriously, just stop using old numpy!
Looks like there's a performance regression from numpy 1.26.4 to 2.0rc1
using the test script from #2970, with all finite data, we have regressed from 56ms to 101ms. with nans present, we have regressed from 130ms to 172ms.
Hmm, probably not easy to bisect numpy
I’m wondering if we should emit a warning when we import numpy if it’s an older version with the clip penalty
Describe the issue: When an in-place ndarray operation is performed with a higher precision numpy scalar value, it took 3x longer on NumPy 2.0rc1 than on 1.26.4. I have read: https://numpy.org/devd...
numpy 1.22.4 slower
I should regenerate that plot after merging
I would like to use a PlotDataItem as a paint brush, with an even fill across pen, points, and interior. However, there is no way to avoid overlap between these graphics items (see screenshot). I found I can paint on an intermediate pixmap with Source CompisitionMode, but there is a severe performance penalty on large drawings. Is there a different way to get a uniform fill intensity across the whole PlotDataItem?
(Ideally it looks something like this, where the points, background, and pen blend uniformly with each other)
(Ideally it looks something like this,
what is this channel for?
I don't know exactly :)
Pyqtgraph is a plotting library, see the channel description
I guess it's for asking questions related to it and discussing it but idk
yeah this channel is specific to the pyqtgraph plotting library, where the server admins have been kind enough to give us a channel
If that PR gets accepted, we will get a big boost for ImageItem
every time I think you can't possibly squeeze more performance out of ImageItem....
too bad numpy/cupy don't have the equivalent of rescale_and_clip
numba_functions.rescaleData's performance is really quite bad
Maybe has to do with the use of guvectorize
alright, bedtime for me, have a good night, thanks again for your patience...
do you think you're done with #2970? (btw love the diff on that PR)
Yes. #2970 is done
I was pondering over whether to break compatibility with numpy < 1.23 . As of now, there's an unnecessary force to C contiguous
eh, no reason to keep compatibility with < 1.23, we stopped supporting it almost a year ago now.
An ROI view of an originally C contiguous image is not C contiguous but would have been contiguous enough
(unless you need to keep it going on your air gapped machine in which case I see why you wouldn't want to introduce unnecessary breakages)
No not for me...
scratch that, we dropped support for < 1.23 only ~4 months ago...
after I merge 2790, I'll likely cut another release, that will be the last one to support python 3.9..
(excited to do the match/case syntax for functions.mkColor)
absent any other PRs that anyone things should be merged prior to the next release, I'm going to make a release today or tomorrow, then bump up min python and numpy versions
In the Symbols example, the horizontal and vertical symbols seem too big compared to the rest
Using symbolSize=14 makes them look more proportional
No idea why the arrow symbols use 22
you have a point...
i'll change it
@fervent vale if you can hold my hand a bit with running asv on your numpy PR, I'll be happy to provide benchmark info for an arm64 platform
OK.
You need to follow the instructions for numpy development
Don't do an editable install
Using editable install mode conflicts with their "spin" command
what's the spin command I need to run to compare your branch vs. main?
I use "spin bench -c HEAD~1 -t bench_clip"
You can't compare against main branch since the benchmark script was added by me
hmm.... I goofed something up, not seeing the spin command
oh, right
oh, pip install spin 🤦♂️
It's important to follow the instructions
The packages to install are in the requirements directory
The two links that I posted above are the important ones
I think it's running, standby
I can't get asv to run on Windows, but other testing shows a speedup of 3x
on battery power:
| Change | Before [c2a9a1cb] <speedup-float-clip~1> | After [96ed0d25] <speedup-float-clip> | Ratio | Benchmark (Parameter) |
|----------|--------------------------------------------|-----------------------------------------|---------|--------------------------------------------------------------------|
| - | 1.18±0.01μs | 1.12±0.01μs | 0.95 | bench_clip.ClipFloat.time_clip(<class 'numpy.longdouble'>, 100) |
| - | 1.37±0.2μs | 1.26±0.01μs | 0.92 | bench_clip.ClipFloat.time_clip(<class 'numpy.float32'>, 100) |
| - | 90.3±0.3μs | 61.2±1μs | 0.68 | bench_clip.ClipFloat.time_clip(<class 'numpy.float64'>, 100000) |
| - | 91.0±0.5μs | 60.4±0.3μs | 0.66 | bench_clip.ClipFloat.time_clip(<class 'numpy.float32'>, 100000) |
| - | 92.7±3μs | 60.4±0.2μs | 0.65 | bench_clip.ClipFloat.time_clip(<class 'numpy.longdouble'>, 100000) |
on wall-power, the ratios are the same.. i'll post in the PR
I was pleasantly surprised that asv's output is markdown and hence gets nicely rendered on github
yeah, first I thought ...this looks clunky...wait...this looks like a markdown table, let me hit the Preview button ...and ✨
It's quite weird that your timings are the same across all the 3 floating point data types
| Change | Before [c2a9a1cb] <speedup-float-clip~1> | After [96ed0d25] <speedup-float-clip> | Ratio | Benchmark (Parameter) |
|---|---|---|---|---|
| - | 5.71±0.02μs | 5.33±0.08μs | 0.93 | bench_clip.ClipFloat.time_clip(<class 'numpy.longdouble'>, 100) |
| - | 2.05±0.01ms | 1.68±0ms | 0.82 | bench_clip.ClipFloat.time_clip(<class 'numpy.longdouble'>, 100000) |
| - | 158±1μs | 77.0±10μs | 0.49 | bench_clip.ClipFloat.time_clip(<class 'numpy.float64'>, 100000) |
| - | 82.6±1μs | 39.4±1μs | 0.48 | bench_clip.ClipFloat.time_clip(<class 'numpy.float32'>, 100000) |
On the RPI5
twice as fast?! 😲
By an accident, I found that ImageItem gets an error with inf (but handles nan fine)
Has been like this for the past few versions anyway
Not sure what inf behavior should be…
So if your image data has an -inf and autolevels is enabled, your offset and scale will be calculated to be -inf and 0. Subtracting an -inf will generate nans.
i've hated that we get the crappy OS default icon when using mkqapp, finally created pyqtgraph/pyqtgraph#2988 to fix that since we now have an awesome icon/logo
groan this PR may have to wait until after I do the next release, looks like the importlib stuff I'm doing is not compatible w/ python 3.9
Why not just bump to 3.10 per NEP 29?
I mean I certainly could; but working around the issue was minor enough…
I may try and patch 2907 and then do the release
I generally don’t like bumping up dependencies right before a release, I try to do that right after a release to minimize the likelihood of someone being caught off guard
While trying to display the highest res peegee png file in an ImageItem, I noticed a slight change in behaviour due to the recent commits (which I think is for the better)
When displaying an RGBA file and autolevels is enabled, ImageItem uses the slow path
The new code refuses to handle images with alpha channel and levels based on the premise that applying levels to the alpha channel doesn't make sense
the 512px@2x is actually 1024x1024, the @2x naming scheme tells the OS to use that icon when scaling is 2.0
I did not actually add the 192px to the QIcon instance, but decided to include it in the repo in case someone else wants to use it.
yeah i'm good w/ that change...
curious how does the peegee icon look on Windows?
Only the window decoration at the top left corner has the tiny icon
The task bar icon is still the regular python icon
Huh! Oh macOS I get the icon on the “dock”. I’ll investigate more on windows
oh, looks like I need to make an .ico file: https://doc.qt.io/qt-6/appicon.html
How to set your application's icon.
actually that's not it, looks like this is it: https://stackoverflow.com/questions/1551605/how-to-set-applications-taskbar-icon-in-windows-7/1552105#1552105
that's better... but noticed the example app isn't recognizing dark mode...
The QIcon class provides scalable icons in different modes and states.
The doc seems to say that loading of the 2x versions is automatic
If a high resolution version of the image exists (identified by the suffix @2x on the base name), it is automatically loaded and added with the device pixel ratio set to a value of 2.
the wording here isn't great... but i can see an interpretation where I just need to QIcon.addFile(basename) but in the case where display scale is set to 2, it automatically loads QIcon.addFile(basename@2x) behind the scenes
was realizing that dark theme on windows wasn't working. ... so trying to get that sorted out... also realized paletteChanged signal is deprecated
getting peak Kranston energy: https://www.youtube.com/watch?v=AbSehcT19u0
I think this is pretty familiar for most of us.
To everyone who watches this: please check out this youtube creator called nartharie . He has created some of the must absurd and funniest videos I've ever seen, but he's still at 280 subs at the time of writing. So please discover this before all your friends or acquaintances or whatever do and be...
On Ubuntu 22.04, the icon doesn't show up on the sidebar either
hmm... I don't have good access to an ubuntu desktop machine to test there
ok got dark theme recognition on windows with Qt 6.5+ .... but now need try and get it for Qt < 6.5
By Ubuntu, that would presumably mean all GNOME desktops
Don't have a KDE desktop around
Qt 6.7 seems to have added dark mode support for Windows
At least the ColorMapMenu gets rendered with a dark background only with Qt 6.7
oh, yeah, in 6.5 it needs the app theme to be set to fusion
which i'm doing when using mkQApp
(about to push my changes, still only local)
created 2992, still need to remove the @2x icons from being explicitly added. .... need to searhc more about getting the application icon working on gnome (or KDE) desktops.
god i love github advanced search, figured spyder folks figured this out and sure enough: https://github.com/spyder-ide/spyder/blob/a9f952ad455690bd88344ff34734b1b5462bb235/spyder/app/utils.py#L303-L305
spyder/app/utils.py lines 303 to 305
# Required for correct icon on GNOME/Wayland:
if hasattr(app, 'setDesktopFileName'):
app.setDesktopFileName('spyder')```
On an Anaconda distribution, if I execute my script with "pythonw", it shows up with the Spyder icon
i just pushed those lines of code (well, equivalent ones) to my branch, if you have some time, would you mind checking to see if #2992 shows the icon on ubuntu/gnome ?
if I just add the setDesktopFileName('pyqtgraph') line to the master branch, it doesn't make a difference
I can try again with your branch if the rest of the commits matter too
No, it didn't show up with your branch either
from importlib import resources
import os
from PySide6 import QtCore, QtGui
traverse = resources.files("pyqtgraph.icons") / "peegee" / "peegee.svg"
with resources.as_file(traverse) as path:
icon_path = path.parent
app = QtGui.QGuiApplication([])
icon = QtGui.QIcon()
for sz in [128, 256, 512]:
pathname = os.fsdecode(icon_path / f"peegee_{sz}px.png")
icon.addFile(pathname, QtCore.QSize(sz, sz))
pixmap = icon.pixmap(QtCore.QSize(512,512))
print(pixmap.size(), pixmap.deviceIndependentSize(), pixmap.devicePixelRatio())
just to verify that the hidpi pixmaps get loaded automatically
setting QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING does disable the auto load of hidpi pixmaps
It's also smart enough such that even if auto load of hidpi pixmaps is disabled, if you have a higher res pixmap loaded, it will use it
e.g. with auto load of hidpi disabled, I request a pixmap of (256,256). It sees that I have a (512,512), so it returns me the (512,512) with dpr set to 2.0
i.e. possibly 128@2x and 256@2x are redundant
but it doesn't hurt to just load all 3 (128, 256, 512)
oh nice way to test that
wasn't sure how to verify (right now setting up an ubuntu VM so I can tinker with trying to get the application icon working there)
How to set your application's icon.
The page talks about GNOME and KDE
Seems that it can only be done if your application installs files into the system
yeah, but the guidance there on windows isn't inline with what works for our case
having the .desktop file is definitely the default way of going about having an application icon on gnome... I'll tinker once this VM is done installing
i love the macbook laptops, but my god, the trackpads on these machines, when using windows (using boot camp on a 2019 macbook pro) is such an awful experience ... no clue how the trackpads can be so great for macOS but so awful on Windows (no doubt the answer is drivers, but still)
dark theme recognition at least works on ubuntu
installing spyder from pip, and launching it shows the spyder icon on the sidebar
(the pip installer could of course have placed a .desktop file in the correct place too)
but you launch spyder as spyder, whereas pyqtgraph scripts get launched as python myscript.py, right?
oh, right, yeah i launch the example app via python -m pyqtgraph.examples
wow, np.clip timings were horrendous on Windows...
i may call it quits on linux, I'm not feeling the urge to make an entry_point as part of the installer for the example app
saw your update to the PR, yeah those timings are rough... funny enough, that PR you have will speed up a tool I sort of maintain at work... one of the slower operations runs np.clip on a pretty large array... but most of the time I'm dealing with integer data
ok, was going to try and do the release before I went to bed tonight...but given I can't type/spell, I think I'll hold off until tomorrow
It won't hurt. Sleep's worth the wait!
i botched a conda-forge config update yesterday too, so I'm on a roll of hosing things up
as long as you don't get a mountain of angry users with pitchforks in your issue tracker, did it really happen?
I already have over 300 issues, not sure I'd notice a mountain of angry users in my issue tracker
I've been trying to keep my github inbox clean lately, I think I would notice :P
(my actual email inboxes are a complete mess, but we don't talk about that)
on Windows with dark mode, the syntax highlighting is not good
yeah probably same issue as macos
you'll notice it gets better if you toggle light/dark mode
I know what I broke 😛
i just force-pushed, try again?
ok, now the comments are visible
tl;dr it didn't attempt to evaluate if the theme at startup was dark or light; it only handled the case when the theme changed...
this was a consequence of me removing the now deprecated paletteChanged signal (and removing other stuff that went with it)
I don't suppose anyone would really complain about an application not handling the live switch of dark/light modes
i would 😛
a nice touch to be sure... but nothing to complain about
alright, release likely tomorrow (I know I said it was today, but now I'm out of excuses)
parameter tree example now gets a blue/gray stripe
Ugh probably a consequence of trimming off the palette changed signal. I’ll look into that tomorrow
Nice catch
Not sure if that's just fusion style
If I don't set the fusion style, then it looks fine on Windows dark mode / Qt 6.7
Windows / PySide6 6.7
huh, weird, looks fine on macOS (although macOS definitely does that alternate row stuff, which maybe we don't want)
ok, some issues w/ fusion theme on Qt5 with dark mode, ...fusion style will now be conditional on Qt6 (seems to work just fine on Qt 6.2)
ok, I think my PR addresses that issue on Windows, ...the alternating row stuff looks nice when done right, but looks so awful when done wrong 😂
hmm.... starting to get complicated with trying to avoid messing with the QApplication instances that were already instantiated before the first call to mkQApp() hate to override the color for the QPalette.ColorRole.AlternateBasebut as I think it's only used for the alternate row stuff, I may just hard-code some values in the ParameterTree class.
not sure if this happens to other people than just me, but feels like I need to go through 10 drafts of code before I go "oh, here's a method that does exactly what I want!" in this particular base, it was QColor.darker() and QColor.lighter()
welp, figured out why I was spinning my wheels so much: https://bugreports.qt.io/browse/QTBUG-113169
Says it’s fixed so might not be that issue specifically
really feeling like this as I'm trying to get the theme handling on both macOS and Windows ... getting it working on one platform seems to break it on another https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExYWJ2Y29uMWl6MTNwdDk5d2V5dHRvbWNhZm1wZWx1NHkzODk1YWQ4NiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/yYSSBtDgbbRzq/giphy.gif
I should note that's what it looks like when you toggle light mode after the application having started on dark mode.
ok got it on windows and macOS, will test on my ubuntu vm momentarily
The behavior that I am seeing on Windows 11 with dark mode is that PySide6 6.2 is light and PySide6 6.5, 6.7 is dark. Is that right?
yeah
Qt didn't start recognizing dark mode on Windows until the Qt 6.5 (with the fusion theme) and 6.7 (or maybe 6.6, I'm not certain on this one) for the "default" theme I believe.
ok, got to the bottom of some race conditions, what's emitted first QApplication.instance().styleHint().colorStyleChanged or QEvent.Type.ApplicationPaletteChanged
I tried out the 2 main scripts that are affected by this change: parametertree example and the ExampleApp
I changed their qapp instantation to QtWidgets.QApplication([])
both become light/dark mode unaware (which is OK)
but the ExampleApp syntax highlighting has become slightly different
compared to the highlighting seen on master
(But of course, ExampleApp is meant to be run using mkQApp)
yeah ExampleApp needs to detect if the existing theme is light or dark, and sets the color of the text based on that, which the bulk of that functionality is in mkQApp() although even if QApplication is instantiated apart from mkQApp() further calls to mkQApp() will inject some of that functionality into that instantiation.
Ah I see that's what the unique connection is for
that PR was one of the most annoying I've done in a loooong time... macOS and Windows behaved completely different... getting it working on one platform had almost no bearing on it working on the other...
also going to move the macOS CI runners to run on ARM processors
the latest intel macOS machine was ~5 years ago
Is the next version going to be 0.13.6 or 0.14? If the latter, then MetaArray can be removed
it will probably be 0.14; I'm marking the dev version 0.13.6dev0 tho
feels safer to hedge in case I broke something
considering bumping Qt6 to be from Qt6.2+ to Qt6.5+ (keeping support for 5.15)
seeing all the red in CI about pyside6 6.2 not being avilable 😂
The last pypi pyside 6.5 wheel actually has a bad bug
It's LTS only for commercial users
yeah the LTS only for commercial users was a real downer
looking at the test suite output for the macOS ARM processors, i'm now having doubts about integrating it right now 😂
This PR workarounds a regression in PySide 6.5.3 that affects code in pyqtgraph's pen parameter.
(https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-2487)
Note: Qt 6.5 is LTS and PySide 6.5...
So PySide6 6.5.3 would not really be the choice of binding to use.
ended up doing the newest of the 6.4 series
the schedule listed there is tough to keep up with...
For open source, you have to live at head
https://github.com/pyqtgraph/pyqtgraph/actions/runs/8769509540/job/24065073337
this is a weird test failure... complaining about not being able to import PySide2, but it should be using PySide6 bindings
alright, getting late, going to merge my PR despite all the red in CI ... i'm open to going back to non-arm chips for macOS CI pipelines
I think you need to specify qt6-main
Or not at all
I think it's no longer necessary to specify qt-main or qt6-main
Yup, both qt-main and qt6-main got installed
suppose I should see if I can replicate some of the macOS failures locally
I can replicate this test failure locally: https://github.com/pyqtgraph/pyqtgraph/actions/runs/8769509540/job/24065074358
ok, now going to bed 😂
Is that the same failure as for aarch64, ppcle64 and riscv?
The last I checked, the coordinate transformations from screen to view were different on different platforms
This ends up with a clicked point that is different across platforms
Then when you draw the line segments, this very slight difference ends up with lines that are very slightly off
Exacerbated by line anti-aliasing
I think so, I’ll have to look at that image diff viewer
Hello I have a question about qt5
Now I am working on submarine drone project. I make my app. I will get data via PyMavlink. I amke design in qt designer. almost i done project. There is one thing that i cant do it. I want to add gyro to my project. I have gyro code in qfi_ADI.py file. I create a layout in design program. And i will add gyro widget to this layout. But it dont show gyro on my app
import qfi_AID
self.gyro = self.findChild(QtWidgets.QVBoxLayout, 'horizontalLayoutGyro')
if self.gyro is not None:
self.adi = qfi_ADI.qfi_ADI(self)
self.gyro.addWidget(self.adi)
else:
print("Error: 'horizontalLayoutGyro' not found")
gyro is like that
if someone want i can send qfi_ADI code also
hard to say from this code, but I would suggest you post more code as a github gist and post in the #user-interfaces channel as this isn't a pyqtgraph specific issue. I don't work w/ QtDesigner, so I can't speak to any issues with that.
woohoo, able to replicate the segmentation fault on the conda/macOS/pyside6 CI pipeline.
bonus, segfaults reliably!
pytest tests -k "not test_PolyLineROI or test_LineROI_coords"
running the first test alone will result in a failure
running the second test alone will pass
test suite passes with
pytest tests -k "not test_PolyLineROI"
Will migrate discussion to an issue but the respective image:
Consistent with aarch64
oh wow, disabling antialiasing did not help lol
on the RPi5, what do you get inside python when you run
>>> import platform
>>> platform.machine()
?
I'm considering making arm64 specific images to test against, I don't like having to tweak the pxCount attribute based on platform
aarch64
I'm leaning towards making separate images for arm64/aarch64/whatever-else
you can't be comparing an non-antialiased image against a saved antialiased reference?
oh....right
so the wrinkle with testing w/o anti-aliasing is that the use of antialiasing is hard-coded into ROI, regardless of what the antialias setting is in the config options.
so I could make an if-check for that inside the paint method for the ROI; ...but.... I'm wondering if there are scenarios where we would want antialiasing for ROIs even if a user specifies pg.setConfigOption(antialias=False)
working on improving the ImageTester widget
(would sure love to know why a test failure in test_PolyLineROI results in a segfault)
It seems that a pip installed pyqtgraph doesn't bundle the peegee icons
oh no...
package_data={
'pyqtgraph.examples': ['optics/*.gz', 'relativity/presets/*.cfg'],
"pyqtgraph.icons": ["*.svg", "*.png"],
I may need to include pyqtgraph.icons.peegee 🤦♂️
Possible to push a replacement wheel?
I mean, I could but that could cause all sorts of issues
would far preffer to release 0.13.6
I think pypi has a mechanism for just such a situation?
I could yank the release, but that just makes the old one inaccessible, doesn't let me push a new one w/ the same version
the only mechanism on pypi I can think of is the yank mechanism, which lets me make a release inaccessible
I could certainly delete the 0.13.5 release and repush it...but then I have to much w/ git tags (I know, it's feasible)...
version numbers are cheap
ok, I think I got the setup.py glob right, let me test
also the conda-forge release would be messed up if I had to redo it like that
ok, will unwind the 3.10/numpy 1.23 requirement in setup.py, do a release of 0.13.6 ...
thanks for bringing this to my attention
alright 0.13.6 released 😅
With 0.13.6 and Anaconda 2023.07, the load of peegee.svg prints an error of "QMimeDatabase: Error loading internal MIME data"
That's with a virtual environment that uses Anaconda system packages + pip pyqtgraph
That's actually PyQt5 5.15.7
I will try without Anaconda and see
i don't get that error on pyqt5 5.15.9 with miniforge-latest (on macOS)
It seems to happen only in the scenario I described
Using an virtual environment with only pyqtgraph installed. And the rest of the packages using Anaconda system packages
If I create a virtual environment without using Anaconda system packages, with the exact PyQt5 5.15.7 PyQt5-sip 12.11.0, no such error message
ok, going to assume not our issue then 😅
i solve it. in qfi path is false
Now i have another problem. I cant refresh data
oh that's interesting, on my branch fix-test_PolyLineROI_on_arm64, I have the px=... arguments commented out, and that one test configruation no longer segfaults, it just fails as it should. The main difference is that I moved the for-loop out of test_PolyLineROI and used @pytest.mark.parametrize
Hi i have a probelm
when i use combobox
my keyboard doesnt work
how can i solve it
i think problem is related with focus
@dry yarrow you should post in #user-interfaces or #❓|how-to-get-help ...this channel isn't intended to debug generic Qt usage.
ok
https://github.com/pyqtgraph/pyqtgraph/actions/runs/8793154468?pr=2999
CI run with ROI test images w/ antialiasing disabled, and testing with antialiasing disabled as well, curious to see how the platforms will fare..
and looking by the results, not well 😂
I'll give you two guesses which environment I created the new test images on 😂
ok, sure enough, without antialiasing, I need much lower pxCount values ( less than 5 in all cases).
I posted on the slack channel trying to get Luke and Martin's attention (they work w/ ROIs a lot) seeing how they felt about the antialias option in ROIs being controlled by pg.getConfigOption("antialias")
my favorite thing in the world is chasing segfaults (that I can't reproduce locally) (I'm being sarcastic)
I think this is the check that's triggering the segfault on ARM + conda + pyqt 5.15 + py312
https://github.com/pyqtgraph/pyqtgraph/blob/master/tests/test_makeARGB.py#L4491-L4493
pijyoi, anything stick out to you about that check?
tests/test_makeARGB.py lines 4491 to 4493
# With masking nans disabled, the nan pixel shouldn't be transparent
im2, alpha = _makeARGB(im1, levels=(0, 1), maskNans=False)
assert im2[3, 5, 3] == 255```
at a glance, it's the only check to use the maskNans=False kwarg
I only ask as I seem to recall you saying something about NaN's with ints being undefined behavior
The value of casting nan to int is not defined in C. It just means that the C compiler doesn't need to ensure that it behaves consistently across platforms
I think it's not even defined what happens if you cast a float value that exceeds the int's dynamic range
next up to try and get a minimum reproducible example, but as I can't reproduce locally, this may be tough (maybe it's an M1 specific issue)
blerg, pyqt6 PyQt6-Qt6 6.7.0 was released, but not PyQt6...
QtGui.abi3.so: undefined symbol: _ZN5QFont11tagToStringEj, version Qt_6
looks like I'm able to get around the segfault
im2, alpha = _makeARGB(im1, levels=(0, 1), maskNans=False)
becomes
im2, alpha = _makeARGB(im1.copy(), levels=(0, 1), maskNans=False)
ugh, this test is sooo huge, should really break up into parametrizations...
So if anything, the segfault would be a numpy issue
Does im1.copy() change the row/col major ordering as a side effect?
After the call to rescaleData, im1 is no longer used
Yeah could be a numpy issue but I can’t replicate locally so really tough to get to the bottom of
Afaik there should be no changing to the row/col major ordering when using the copy, that test doesn’t dependent on im1 mutating.
Still think as a matter of best practice that test needs to be broken up and then have pytest parametrization applied for greater simplification, and probably some better resource management under the hood
i seemed to get around this issue by doing im1.setflags(write=False) ... I also moved some stuff out of that test (the exception handling checks) ... still feel like I should break this test file up more tho (but CI on this branch is all ✅ )
Hi, how can i integrate tensorflow ai camera to my project which i input my camera like below:
self.viewfinder = QCameraViewfinder()
self.viewfinder.show()
self.layout = QtWidgets.QVBoxLayout(self.cameraPlaceholder)
self.layout.addWidget(self.viewfinder)
camera_info = QCameraInfo.availableCameras()
self.camera = QCamera(camera_info[0])
self.camera.setViewfinder(self.viewfinder)
self.camera.start()
if QCameraViewfinder() is a QWidget, then you can integrate it like any other QWidget?
yes i think
pgWidget = pg.GraphicsWidget()
self.layout.addWidget(pgWidget)
now you have a pyqtgraph plot widget next to your camera ?
i think I get the segfault resolved, I go to cleanup the code a bit, not only does the segfault come back, but it starts setfaulting on another pipeline ...just wonderful
my code is in pyqt5
if u want i can send .ui .py and ai code also
i don't use .ui files, but maybe this article would be of help: https://www.pythonguis.com/tutorials/pyside-embed-pyqtgraph-custom-widgets/
every time I think I'm done tinkering in a PR, I realize something else I should do "while I'm here"
... I have a sickness. Now I'm running the coverage tool to see what bits of functions.makeARGB are not being executed to add more test cases ....
And merged. CI is all green…
and now the segfault is still there :fliptable:
The original issue was #1698
It was asking for a way to set FillRule to WindingFill https://doc.qt.io/qt-6/qt.html#FillRule-enum
The Qt namespace contains miscellaneous identifiers used throughout the Qt library.
Maybe there's no need for the implementation in #2971 and #3006 if the user can set FillRule?
ugh, that's what i get for not reading the original issue closer
i have the toy example loaded up, let me see if I can add an extra arg to edit the FillRule would be sufficient
with undoing the changes in 2971, and 3006, and setting a fill rule in the QPainterPath instance in FillBetweenItem.updatePath, I don't get the desired result with either fill rule unfortunately
that said, I think adding the option to specify the fill rule is a good idea, and easy enough to do
So #2971 is actually addressing another problem than #1698
yeah, several ways of looking at it.
#2971 fixes the issue highlighted with the sample code in #1698, but it does not implement what the user was asking for.
The sample code in #1698 when run with either FillRule's has the same result, so probably just a bad example.
Anyway I'm going to unwind the change from #2971 and add an arg and set/get methods to set the FillRule
I'm now starting to wonder why the example code in 1698 doesn't work w/ setting the FillRule to WindingFill
Specifies that the region is filled using the non zero winding rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape. Determine whether the direction of the line at each intersection point is up or down. The winding number is determined by summing the direction of each intersection. If the number is non zero, the point is inside the shape. This fill mode can also in most cases be considered as the intersection of closed shapes.
"this fill mode can also be in most cases be considered the intersection of closed shapes"
so I guess it's not definite that it will fill enclosed shapes
ok, got FillBetweenItem working as expected to accept the FillRule using that example, but I had to make a change in the updatePath method that I suspect may have some consequences:
# ps2 = paths[1].toReversed().toSubpathPolygons(transform)
# ps2.reverse()
ps2 = paths[1].toSubpathPolygons(transform)
ugh, thanks for keeping me honest on #3007 pijyoi, I did know the alpha channel was set explicitly but still managed to butcher it ...anyway I'll update accordingly... once I confirm my PR for the FillBetweenItem works as expected and merge that, I'll likely cut another release ... I try and not let regressions linger
managed to get the segfault to happen locally, macOS gave me a crash log, not sure if it's helpful
ok, I think the maskNans was a red herring, I'm only reproducing the segfault intermittently so I have to run pytest like ...10 times before I develop confidence if my change has actually made a difference
segfault occurs somewhere in here... proceeding to narrow down more..
lut = np.zeros((256, 3), dtype='ubyte')
lut[:, 0] = np.arange(256)
lut[:, 1] = np.arange(256)[::-1]
lut[:, 2] = 7
im2, alpha = _makeARGB(im1, lut=lut)
EDIT: segfault appears to occur inside try_fastpath_argb
maybe it's time to retire try_fastpath_argb then
that code was put in before the try_make_qimage code came into being
I would also consider removing numba_functions.rescaleData
narrowed down the issue to somewhere in this codeblock:
while row_beg < nrows:
row_end = min(row_beg + batch, nrows)
ain_view = ain[row_beg:row_end, ...]
aout_view = aout[row_beg:row_end, ...]
qimg = QtGui.QImage(ain_view, ncols, ain_view.shape[0], ain.strides[0], in_fmt)
qimg = qimg.convertToFormat(out_fmt)
aout_view[:] = imageToArray(qimg, copy=False, transpose=False)
row_beg = row_end
if we can retire try_fastpath_argb and use try_make_qimage instead, I'd be all about that
It might be a Qt or numpy bug that is accessing memory out of bounds
I suspect it's Qt...
on my machine I'm only able to replicate on older PyQt6 bindings, on CI this only occurs on macOS + conda + PyQt5 (there are no PyQt6 conda bindings yet)
but I think that code chunk is due for retirement
I haven't worked w/ makeARGB nearly as much as you have (or really at all for that matter 😅 ) would this be a case where I can just remove references to fastpath inside makeARGB or is there something else I should do?
yup, just remove it.
actually, it's considered an error for me if my own code triggers the makeARGB path...
removed the fastpath, 10 test runs so far, no segfault
<pushes to CI, immediate segfault> (joking, but feels like that's how this has been going 😂 )
I really need to add a Performance section to the ImageItem docs that details the combinations that support try_make_qimage
and indeed no segfault 😅
That can currently be summarized as {uint8, uint16, float32, float64} x {1 chan, 3 chan} so long as levels is not multi-channel
4 channel images will work too, if levels=None (which then precludes float)
choose luts that have not more than 256 colors
Use ImageItem::setColorMap rather than ImageItem::setLookupTable
if you call ColorMap::getLookupTable, the default number of colors returned is 512
i.e. if you copy and pasted code from somewhere that does
cmap = pg.colormap.get("viridis")
lut = cmap.getLookupTable()
imgitem.setLookupTable(lut)
then you trigger a slower path
not a chance i can write this up today, ... my wife is already side-eyeing me with the time i've working on the library the last few days...but I want to resolve the FillBetweenItem regression next.
i'm making so many mistakes it's like I'm coding drunk... thanks for keeping me honest.
got it, turns out didn't need any chances in fill between item (beside saccepting the fill rule) but had to reverse the order of the x/y points for the second PlotItem
I think it's time to retire setup.py... before I start work there, I'm going to want to make sure no more regressions got introduced in 0.13.5 😂
Ubuntu 24.04 managed to pick up 0.13.4 https://packages.ubuntu.com/noble/python-pyqtgraph-doc
nice!
i'm a little nervous about removing all the linux package build stuff in setupHelpers, but outside of the asv stuff I really want to remove all that stuff
any other CI changes that you think should happen that I haven't specified here? https://github.com/pyqtgraph/pyqtgraph/pull/3016
can't say I understand much of what's going on there.
Don’t worry about the diff, just curious if you think there still be other tasks we want our CI system to do, I’ll add them as subtasks to the first post
congratulations pijyoi https://github.com/numpy/numpy/pull/26280
can't wait to see what the speedups for ImageItem are now, especially on Windows
np.clip with floating point values is slower than it should be due to having to check and propagate nans.
This PR speeds up the operation by:
checking that vmin and vmax are not nans only once.
wr...
I think I saw a 30% boost in VideoSpeedTest a week ago.
Numba since 0.13.5 was more than 2x compared to NumPy 1.26.4
Think this PR closed the gap to under 2x
do you know if numpy plans on doing a 1.27 release or are they going straight to 2.0?
All indications are that 1.26 should be the last
In any case, this won’t land until 2.1
It got merged into 2.1.0dev
maybe they'll backport it , but probably not
ugh, i should try and catch/filter those in functions.disconnect()
You can't do that now. The current remaining warnings are not suppressible
Not until PYSIDE 2705 lands
okay, it seems like with PYSIDE-2705 "fixed", instead of a RunTimeWarning, we get a SystemError: <method 'disconnect' of 'PySide6.QtCore.SignalInstance' objects> returned a result with an exception set instead
So CI will start failing once PySide6 6.7.1 gets released
guess i should make a PR to add SystemError to the list of exceptions in functions.disconnect() that are caught?
It's a PySide6 bug that should get fixed down the road
i really need to get that manually triggered CI setup for testing pre-releases of pyside6 and pyqt bindings...
I don't imagine anyone happens to know how to install pyside6 pre-releases via pip? I tried
pip install --index-url=https://download.qt.io/official_releases/QtForPython/ --trusted-host download.qt.io --pre pyside6 shiboken6 but it didn't seem to find py3.12 wheels on macOS there (about to see if the install command will work for 3.11)
pip install --no-index --find-links https://download.qt.io/snapshots/ci/pyside/dev/latest/split_wheels/ --force-reinstall PySide6_Essentials
hmm... getting
ERROR: Could not find a version that satisfies the requirement PySide6 (from versions: none)
ERROR: No matching distribution found for PySide6
(same w/ PySide6_Essentials )
pip install --no-index --find-links https://download.qt.io/snapshots/ci/pyside/dev/latest/pyside6-essentials/ --force-reinstall PySide6_Essentials
How about that?
yup
Qt may have changed their paths over time
that works
The "split_wheels" one was a cut and paste from message history 6 months ago
pip install --no-index --find-links https://download.qt.io/snapshots/ci/pyside/dev/latest/pyside6/ --force-reinstall PySide6_Essentials
This should work too
Possibly slicing off the last "pyside6" might work
i'll tinker with that, I just realized the image comparison image test failure never uploaded an artifact of the failed image...
so fixing that first 😬
(well, it worked back when I had the CI on Azure Pipelines I think)
Think all the subdirs in this directory are just links to one another
yeah i think so too, if they weren't links to one another, it wouldn't have found the shiboken6 package
unfortunately this one doesn't seem to work :/
got one of the other links to work, that's good enough until their URL structure changes 😂
that's more like it...
the CI stuff can sure be annoying because a lot of it won't work from a branch that's a PR, but the config needs to be on master/main ... anyway I guess that's why we have our own forks...
welp, this isn't good, the pre-release install is crashing on virtually all pipelines: https://github.com/j9ac9k/pyqtgraph/actions/runs/8955326012/job/24595910288
it's weird, pyside/pyqt5|6 ...all in the same place, like I'm forgetting to grab some needed dependency
ok, now starting to get closer to passing...
oh, that's because it's trying to build the wheels on the CI machine from the source distribution ...
why on earth do the windows/pyqt5|6 pipelines fail due to not finding setuptools when building the pyqt5|6 wheels https://github.com/j9ac9k/pyqtgraph/actions/runs/8955448865/job/24596151687
Collecting PyQt5
Downloading https://www.riverbankcomputing.com/pypi/packages/PyQt5/PyQt5-5.15.11.dev2402201716.tar.gz (3.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.2/3.2 MB 4.3 MB/s eta 0:00:00
Running command pip subprocess to install build dependencies
Looking in indexes: https://www.riverbankcomputing.com/pypi/simple/
Collecting sip<7,>=6.8
Downloading https://www.riverbankcomputing.com/pypi/packages/snapshots/sip/sip-6.8.4.dev15%2Bgaeb556e8-py3-none-any.whl (468 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.2/468.2 kB 1.1 MB/s eta 0:00:00
Collecting PyQt-builder<2,>=1.14.1
Downloading https://www.riverbankcomputing.com/pypi/packages/snapshots/PyQt-builder/PyQt_builder-1.16.2-py3-none-any.whl (3.7 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.7/3.7 MB 8.1 MB/s eta 0:00:00
Collecting packaging (from sip<7,>=6.8)
Using cached packaging-24.0-py3-none-any.whl.metadata (3.2 kB)
Using cached packaging-24.0-py3-none-any.whl (53 kB)
Installing collected packages: packaging, sip, PyQt-builder
Successfully installed PyQt-builder-1.16.2 packaging-24.0 sip-6.8.4.dev15+gaeb556e8
Installing build dependencies ... done
Running command Getting requirements to build wheel
Getting requirements to build wheel ... done
it looks like the build dependencies on the custom index are out of date? they aren't pulling in setuptools as a transitive dependency
seems to be working on pyqt6 on windows...
I don't think we should build any wheels from source
pyqt doesn't provide any wheels tho? (from their index)
About a week or two before release, Phil provides wheels
ahh, ok, i'll specify only binaries then...
still would love to know why all ubuntu pipelines are segfaulting https://github.com/j9ac9k/pyqtgraph/actions/runs/8955448865/job/24596151471
I did build PyQt6 from source on Windows before. I think it was self contained. No Qt install needed
Why it even worked didn't occur to me at the time
I think Qt is pulled it via PyQt6-Qt6 package?
welp, specifying --only-binary :all: as part of the CI pipeline breaks all the CI pipelines since it can't find a matching compatible PyQt-sip version 😂
the pyside6 bindings fail for that SystemError bit you gave me the heads up about, and the ubuntu pipelines that make it to the test suite just segfault :/
Maybe need a --no-deps
The riverbank pypi repo is not self sufficient
pip install --index-url https://riverbankcomputing.com/pypi/simple/ --no-deps --pre --upgrade PyQt6
That's the line listed on the PyQt pypi page
but how do I get the sip package?
this seems to be doing the trick:
python -m pip install --index-url https://www.riverbankcomputing.com/pypi/simple/ \
--pre \
--only-binary=PyQt6 \
PyQt6
going to go to bed, but will want to try and evlauate the segfaults in linux a bit more before merging this
here's the last run, the pyside failures on windows/macOS can be ignored, the pyqt5 errors on windows are due to a lack of a wheel being found, but no idea what's going on with ubuntu jobs: https://github.com/j9ac9k/pyqtgraph/actions/runs/8955598076/job/24596482679
I get the same "Fatal Python error: Aborted" message on my RPI5 when I ssh in and run "pytest -v tests". Things run fine when I run through vnc.
I didn't want to try setting up Xvfb, given that RPI OS runs wayland by default and install Xvfb would have installed a whole bunch of things
As a test, you could try changing "pytest -v tests" to "pytest -v tests/test_functions.py" and see how far that goes.
That does run fine on RPI5 over ssh
The numpy nightly wheel can be found here: https://anaconda.org/scientific-python-nightly-wheels/numpy and includes the speedup to np.clip
I was testing it out and it seems that VideoSpeedTest has a much lower framerate on PySide6 6.7 vs 6.6
Now, this may just be that screen refresh is lower on PySide6 6.7
But anyway, with PySide6 6.6.3 and Windows, the fps for numpy 1.26.4, numpy nightly, numba are respectively 103, 120, 180
And on PySide6 6.7.0, they are 61, 71, 90
VideoSpeedTest is run with --size=1920x1080 --dtype=float --levels=0,2
A more useful metric are the examples from #2970
Where adjusting histogram levels results in little lag even for large images (6000x4000 in the example)
render() time being 56ms, 43ms, 12ms for numpy 1.26.4, numpy nightly, numba respectively
Wake up in the morning, first thought “oh, I forgot to install pytest-xvfb on that CI pipeline, that explains it blowing up”
I need to stop coding late at night.
Do you think I should add a numpy nightly job here as well?
Probably not.
Numpy is quite stable. And rightly so.
sure enough, added pytest-xvfb and the linux pipelines are running just fine
There's probably no need to test PyQt5 anymore for the manual
yeah I was on the fence on that one, but you're right, we're effectively testing the sip stuff at that point...which should be covered by the PyQt6 test
ok, next up, need to get my dash docset submission to be automated... and then I think this PR is done
oh oh oh ... just noticed that the dependency graph is now working and lets us filter by repos that have packages... I can't sort by stars or forks, but I can browse through (there are 703 "packages" that use pyqtgraph as a dependency).
Some super interesting ones that I was unaware of:
https://github.com/DaloroAT/first_breaks_picking
https://github.com/tlambert03/cmap
pyqtgraph used for language learning?!??!?!
Any Dash docset users here? Just submitted pyqtgraph docset to the community docset contributions: https://github.com/Kapeli/Dash-User-Contributions/pull/4940
and already merged 🎉
and already available:
just ran the test sutie through python 3.13.0b1 and numpy 2.0.0rc1 and everything passed, no new deprecation warnings or anything like that
@fervent vale that PR brings a (happy) tear to my eye 😂
it's unknown why numba jit-ifies np.nditer to faster code than guvectorize
The QRhiWidget class is a widget for rendering 3D graphics via an accelerated grapics API, such as Vulkan, Metal, or Direct 3D.
might be a while before support is rolled out to python bindings... but there are significant implications to pyqtgraph if this works as expected in the python bindings
looks like QRhiWidget is in PySide6 6.7.0 (but not in PyQt6 6.7.0)
Phil's response to request for support
@plush fulcrum does matplotlib have dynamically wrapped methods the way pyqtgraph does? If so, how do you do type annotations on them?
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/PlotItem/PlotItem.py#L268-L279
pyqtgraph/graphicsItems/PlotItem/PlotItem.py lines 268 to 279
for m in ['setXRange', 'setYRange', 'setXLink', 'setYLink', 'setAutoPan', # NOTE:
'setAutoVisible', 'setDefaultPadding', 'setRange', 'autoRange', 'viewRect', 'viewRange', # If you update this list, please
'setMouseEnabled', 'setLimits', 'enableAutoRange', 'disableAutoRange', # update the class docstring
'setAspectLocked', 'invertY', 'invertX', 'register', 'unregister']: # as well.
def _create_method(name):
def method(self, *args, **kwargs):
return getattr(self.vb, name)(*args, **kwargs)
method.__name__ = name
return method
locals()[m] = _create_method(m)```
issue for the discussion for context: https://github.com/pyqtgraph/pyqtgraph/issues/3023
Yeah... in general dynamic behavior is not conducive to static type checking...
In mpl, we do have some aliasing that is handled by a class decorator, such as set_ha which is the short form of set_horizontalalignment (among many others). We have opted to not type hint those things that are aliased dynamically like that. In our case the official guidance is to use the canonical name in the type checked setting, which is type hinted.
In mpl's case, we technically have the ability to put the type hints in the .pyi files, but I chose not to since it seems silly to expand out the class decorator, and it would make it harder for us to inline type hints should we ever choose to do so (no active plans though on that front)
As for CI, we have a file with specific ignores (for stubtest, which is mypy's program to validate .pyi files against implementation), which actually includes almost everything except the aliases and such, because we generate the most common cases with a script, so that individual PR authors don't have to think about the stubtest exceptions as often:
- https://github.com/matplotlib/matplotlib/blob/main/ci/mypy-stubtest-allowlist.txt
- https://github.com/matplotlib/matplotlib/blob/main/tools/stubtest.py
In this case, I think perhaps rewriting these so that they are more static friendly may be possible...
Not finding the obvious solution immediately, but feels possible, I think one step would be unrolling the loop, which I think will help static checkers...
In mpl we have a similar pass through implented as _axis_method_wrapper for various things that are wrapped in Axes that are actually canonically held in the x/y Axis. However in this case I just typed them in pyi
lib/matplotlib/axes/_base.py line 35
class _axis_method_wrapper:```
`lib/matplotlib/axes/_base.pyi` line 253
```py
def get_xmargin(self) -> float: ...```
@plush fulcrum we've had a surprising recent interest from non-maintainers into getting type annotations into the library, given my knowledge there is in the basics ... I'm trying to let those more knowledable than me lead the discussion, and I'm trying to just define some constraints (we need aliases for complex type-unions, I want to stay away from pyi files unless we can verify our own implementation against them, etc)
stubtest does allow verifying against implementation to a degree... in that it checks that runtime signatures of methods match the stubs. What it does not do is ensure line by line that every internal usage is consistent with type hints (which inline will check).
I think there may be a way to get pyright to do some of that, but pyright was too noisy for mpl to start out with, and cutting it down has not been a focus of mine
yeah... doesn't sound like stubtest is right for us then
I'm fine w/ the .pyi files for the annotations from the Qt bindings in our abstraction layer; but that's because it's just linking to the annotations in our dependencies
that said, I'm not sure the stubs are working w/ relative imports either...
QRhiWidget seems to be the replacement for QOpenGLWidget, so it shouldn't affect the Graphics View framework, which itself is not seeing any more development by Qt.
Yeah, but we are no longer limited to OpenGL, or OpenGL 4.1 (for major desktop platforms, or 2.0 if we include embedded)
Rule 1: instantiate ImageItem with axisOrder="row-major"
setColorMap rule is more for simplicity. It does the right thing without any further parameters. Whereas setLookupTable requires a getLookupTable(nPts=256)
As the default is nPts=512
Pyqtgraph doesn't really support 4 channel data because the 4th channel is alpha. So yes, the guidance is correct that 4 channel data should use levels=None, but only because it doesn't make sense to globally adjust all channel levels of an RGBA image
I found an old script that displayed a large image 60Mpix using ImageView that set auto down sample to True, and even then it was struggling.
Now I can display 162Mpix with numba and change levels on the histogram smoothly
Without any down sampling
The 60Mpix was a crop of the 162Mpix to make the problem smaller
It's a float image
So in terms of responsiveness of the HistogramLUTItem with this 162Mpix image, numpy 1.26 takes 300ms, numpy nightly takes 165ms, numba takes 80ms
I also found out that ImageView is not adapted to cupy
And furthermore, a compiler is required to be present in order to use anything slightly more complicated in cupy
E.g. xp.nanmin (used for autolevels) will trigger compilation on cupy
It just so happens that VideoSpeedTest.py is setup such that no compilation gets triggered with cupy
Cupy seems not so suitable for the end user
Especially on Windows anyway
Where a compiler is not normally present
I'll reword some of the bullets to be ore clear...
that's dissapointing about CuPy, is there a combination of args where CuPy out-performs numba? I should redo that chart I had from earlier... or figure out how to automate the generation of it and include that in the docs
VideoSpeedTest works without compilation only because levels are set.
We don't see the compilation error because when levels aren't "set", we are actually calling with "levels=None", which is a different meaning from not passing on a levels argument
Cupy caches the compilation result so subsequent executions should be fast
We didn't configure numba to cache to disk
So I suppose regarding cupy, if you were already using cupy for your computation, then yes pyqtgraph supports passing in of the cupy array
If you are only using pyqtgraph and looking to speed up display, it would be too much hassle to make use of cupy
setLookupTable doesn't take a nPts parameter
It's ColorMap.getLookupTable that takes a nPts parameter defaulting to 512
from 2013 😢 ... emoji due to being constrained to default parameters/methods set from over a decade ago
Interesting point made about documentation needing to be good so that AI coding assistants can generate better code
i would imagine the AI assistants would make better use of the examples, but yeah, the documentation needs a ton of work
trying to get an equivalent pyqtgraph plot from matplotlib is definitely a losing proposition
I would like to migrate our documentation to use the myst markdown from restructured text ... the documentation infrastructure has come a long way over the last few years (before used to be a script that Luke would periodically run and host the docs on his web server, no versioning information) ...but admittedly the content hasn't gotten the same attention.
https://www.pyopensci.org/ These folks offered to "audit" our docs, ... I was considering requesting that they do so after I patch up the most eggregious issues
From their website, I couldn't really find examples of packages that have gotten peer reviewed by them
They’re pretty active in social media, I’ll ask for examples of their past feedback. I think they’re at pycon right now
I am doing a Rhi hello world : RawImageRhiWidget
almost done w/ the ImageItem docuemntation overhaul ... Only thing I need to figure out is how to properly document the signals so they look similar to the Qt docs
getting the "signals" bit to render like that took a bit of effort! 😂
new ImageItem docs page, feedback welcome/appreciated: https://pyqtgraph--3028.org.readthedocs.build/en/3028/api_reference/graphicsItems/imageitem.html#imageitem
The one thing I don’t like is that I have the “return” and “return type” section for the method(s) that have a return type annotation
“This only works if levels is 1D (not multi-channel)”: the performance guidelines is advisory. It works if it’s not 1D, just that it won’t take the fast path.
“such that makeARGB() is called should be considered an error.”: that’s just my take on my own code, wording it as such in the docs is overly strong
Outside of the performance section, there is also no mention of nans being part of the official API to mark the pixel as transparent
You’re right “works” is the wrong word for sure
Good point. I’ll add a note about that.
Updated, added the blurb about the nans in the docstring for setImage, removed the blrub about "considered and error" and "works" for levels...
still need to address the "Return" and "Return Type" bits...
ok, can't do away with return type bits, and the duplicate annotations, but at least the rendered documetnation doesn't have duplicated types...
not immediately runnable as is. needs the compiled shaders from Qt's cuberhiwidget example
pyside6-qsb.exe exists in Qt nightlies but fails to run. It's probably trying to launch the actual Qt tool, but that means one needs the Qt SDK
so on my Windows machine it uses Direct3D11; and on the RPI5, it's OpenGL
"Setting levels=None will trigger autoLevels sampling, and thus should be avoided if possible.": this is not correct.
There's a difference between not supplying the argument at all, vs setting "levels=None"
Actually to describe the full logic would be backwards, in my opinion
"if autoLevels is not set, its value is determined by the following logic: if "levels" argument is supplied, including "levels=None", then that implies "autoLevels=False"
very convoluted...
#2883 was trying to fix that
Yeah… it’s awkward
the meaning of "autoLevels=False" is different from "autoLevels=False levels=None"
The former leaves the previous setting of "levels" alone
"levels=None" is equivalent to "autoLevels=False levels=None"
re-reading the setLevels docs, that needs an update too, so added a blurb there.
@torn coyote a maintainer has re-entered chat! Good to hear from you, hope all has been well.
didn't realize I could do the : more info on the See Also section... this cleans things up a lot
@torn coyote if you can think of a way to solve this "issue" (rendering difference of parameters when using numpydoc vs. napoleon) let me know! I greatly prefer how numpydoc renders the parameters within the docs, but we're definitely dependent on napoleon not just because we have a mountain of sphinx/google style docstrings, but due to the custom section name ("signals") and some of the integration of the in-line annotations.
https://stackoverflow.com/questions/73207795/sphinx-and-read-the-docs-not-using-numpy-docs-style
Reading more about this issue, looks like if we want rendering like that, we need to migrate to numpydoc ... so yeah, I guess that's going to be a future thing
I wouldn't mind having a set of numpydoc rules to validate against so we can test that new docstrings (or changed docstrings) conform to the rules we specify...
As an exercise, I have ported the RawImageGLWidget (that nobody uses) to not use PyOpenGL on my own branch.
is this the modern_opengl branch?
Yes
Does the raw image widget work with video speed test? I know it’s selectable but not sure if it actually “works”
I’ll try it out later today
Yes it does
Although my primary test is a script that displays the peegee image
Based on the code history, RawImageGLWidget must have been a cut and paste of GLImageItem
The scale attribute does nothing while the smooth attribute has no setter
I find the peegee image useful for creating standalone demonstration scripts
do you use the SVG or load in one of the pngs in the icons directory?
I load the largest png using QImage.
I want to start including more images in the docs (for a plotting library, we have remarkably few images) ... the peegee icon may be a great starting place to use a test image throughout
Actually the 512@2x image is very heavyweight, bytesize-wise
should I attemp to "optimize" the png?
ImageMagick doesn't compress it any further
The alpha is not binary
I.e. Not just 0 or 255
Nils gave me a bunch of "updated" icons of various sizes; still haven't added them to the repo (they're smaller in size tho)
this one include a gradient background...
back to the RawImageGLWidget, didn't you say something a while back about the pyside opengl bits not working due to references? ... <going to search now>
I think it was glGetIntegerv and friends
if you can give me a MRE I'll open an issue on the bug tracker with pyside; the folks there have been mostly responsive
also looking at your branch, do you have strong feelings regarding the shader source code inside the triple quotes (in your get_shaders_src_compat/core methods) ? I know that's perfectly valid but it still seems weird to me. wondering if those should live in their own files (with the appropriate extension so we can get linting in various editors and so on) ... I know that the code here is small enough it doesn't matter... but curious if you think it should be organized differently
I think at least for now it's easier to maintain within the same file
PyQt supports only 2.0, 2.1, 4.1 core
i'm good w/ 4.1 core
wish macos would do open 4.3 so we can use compute shaders 😦
seems like those would be useful
(but if PyQt doesn't support it, doesn't matter)
more correctly speaking, the PyQt exposes only QtOpenGL functions for 2.0, 2.1, 4.1 core
if you use PyOpenGL, you won't get restricted by PyQt
I don't have an issue w/ pyopengl dependency, I can only recall one issue historically with it, and it was more of an issue w/ python itself (was specific to macOS). Do you have opinions on whether we should keep pyopengl or try and migrate to the QtOpenGL?
QtOpenGL was meant to allow a single code base to use either GLES or Desktop OpenGL, which means that functions like glBegin/glEnd are not wrapped
o! that's handy
So there would be no incremental porting of the GLItems
alright, I got it to work with OpenGLES. Tested on Windows / PySide2 / ANGLE by using AA_UseOpenGLES
Turns out that PyQt5 doesn't support GLES
(probably for the same reason that it only supports 2.0, 2.1 and 4.1 core)
do you think that is a limitation of PyQt5 or the version of Qt it bundles with it, if I remember right, Phil said he doesn't recompile Qt, he just wraps it in the PyQt5-Qt package and ships it that way
In the code to fetch glfn, you will notice that PyQt5 has its own path, a method called "versionFunctions". A call to that with ANGLE enabled says "Not supported on OpenGL ES"
So the Qt libs have already switched to ANGLE and presents an OpenGL ES context
import sys
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
# QtCore.QCoreApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_UseOpenGLES)
pg.setConfigOption('imageAxisOrder', 'row-major')
pg.mkQApp()
win = QtWidgets.QWidget()
vbox = QtWidgets.QVBoxLayout(win)
img = pg.RawImageGLWidget()
qimage = QtGui.QImage(sys.argv[1])
qimage.convertTo(QtGui.QImage.Format.Format_RGBA8888)
image = pg.functions.ndarray_from_qimage(qimage)
img.setImage(image)
vbox.addWidget(img)
win.destroyed.connect(img.cleanup)
win.resize(640, 480)
win.show()
pg.exec()
My tester script
unfortunately, a wrapper QWidget is needed to call the cleanup
The QOpenGLContext class represents a native OpenGL context, enabling OpenGL rendering on a QSurface.
The recommendation there to use hideEvent() is wrong, IMO.
While I may not have your code skills to contribute to numpy, I’m about to try and contribute to numpydoc 😂
ok, the glGetIntegerv problem seems to have been fixed sometime after PySide6 6.2
ok, glGetIntegerv works in PySide6 6.5, 6.6 but crashes for multiple value return in 6.7
from PySide6 import QtGui, QtOpenGL
from OpenGL import GL
import numpy as np
app = QtGui.QGuiApplication([])
surf = QtGui.QOffscreenSurface()
surf.create()
ctx = QtGui.QOpenGLContext()
ctx.create()
ctx.makeCurrent(surf)
profile = QtOpenGL.QOpenGLVersionProfile()
profile.setVersion(2, 0)
glfn = QtOpenGL.QOpenGLVersionFunctionsFactory.get(profile, ctx)
print('VENDOR:', glfn.glGetString(GL.GL_VENDOR))
print('RENDERER:', glfn.glGetString(GL.GL_RENDERER))
print('VERSION:', glfn.glGetString(GL.GL_VERSION))
print('MAX_TEXTURE_SIZE:', glfn.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE))
print('MAX_3D_TEXTURE_SIZE:', glfn.glGetIntegerv(GL.GL_MAX_3D_TEXTURE_SIZE))
print('LINE_WIDTH_RANGE', glfn.glGetIntegerv(GL.GL_LINE_WIDTH_RANGE))
mat = QtGui.QMatrix4x4()
for data in [mat.data(), list(mat.data()), np.array(mat.data(), dtype=np.float32)]:
print(f'* Trying {type(data)}')
try:
glfn.glLoadMatrixf(data)
except Exception as e:
print(e)
the MRE. doesn't really need numpy. PyOpenGL just for the constants
LINE_WIDTH_RANGE returns 2 values and crashes 6.7 (on Windows)
all sorts of stuff seems to crash on pyside 6.7; had a work-based application that i package w/ pyinstaller crash on me between 6.6.3 and 6.7.0
glLoadMatrixf doesn't work up through 6.7
bug tracker is full of stuff...
anyway I can open an issue easily enough
but maybe no one cares, because you are supposed to be using shaders and load the matrix as a uniform
6.2 can't even load single value glGetIntegerv
it occurs to me that I can't even try out RawImageGLWidget on a "real" GLES device
Qt is only compiled for GLES on 32-bit linux images
Since PyQt doesn't support GLES, the distro-packaged PyQt wouldn't work
PySide6 only provides aarch64 wheels
well, getting that regex took me longer than I would have liked to admit: https://github.com/numpy/numpydoc/pull/558
so there are 3rd-party 32-bit wheels
is the idea here to see how well a RPi could handle RawImageGLWidget?
