getArrayRegion axes argument

281 views
Skip to first unread message

L. Smash

unread,
May 19, 2015, 10:30:48 AM5/19/15
to pyqt...@googlegroups.com

Hi guys,

I have an issue with the "axes" argument in the getArrayRegion function.
There was an example on how to use it:

win = pg.GraphicsWindow()
view = win.addViewBox()
data = np.random.normal(size=(100,100,100))
img = pg.ImageItem()
img.setImage(data.mean(axis=0)) # img x and y axes are data axes 1 and 2
roi = pg.RectROI(pos=[120, 120], size=[20, 20])
view.addItem(img)
view.addItem(roi)

## let user move ROI, then pull out selected region:
roiData = roi.getArrayRegion(data, img, axes=(1,2))

However, it seems that this only works for rectangular ROIs. When I replace the rectROI by e.g.
 

roi = pg.PolyLineROI([[50, 10],[50,50],[70,50]], pen=pg.mkPen('b'), closed=True)


and then display roiData, I get some strange images. A CircleROI even gives me "getArrayRegion() got an unexpected keyword argument 'axes' ". Im I doing something wrong here or does "axes" only work with rectangular ROIs?

Best,
Lars

Julien Lhermitte

unread,
May 21, 2015, 8:46:44 AM5/21/15
to pyqt...@googlegroups.com
Lars,

     To answer the second question, you have caught a "bug" (in quotes because it's not really a bug).
Basically, the "axes" flag needs to be passed on. I have submitted a pull request so that it might catch attention (seems like response activity on this forum is low).

For the strange images, what dimensions are your images? Default seems to be axes=(0,1) so if you're using axes =(1,2) could be the issue. (I think you have already done this but just asking first)

L. Smash

unread,
May 21, 2015, 11:17:29 AM5/21/15
to pyqt...@googlegroups.com
Hi Julien,

yes, default should be axes=(0,1). The image dimensions seem always to be right ((dimensions of selected roi), 100). My idea was that since 'data' is an 100x100x100 array, no matter what axes are chosen the result of getArrayRegion should always look the same, namely just noise with shape ((dimensions of selected roi),100).

Everything other than axes=(0,1) gives something else I cannot explain. For now I just use the default (0,1) axes and use 'roiData = roi.getArrayRegion(data.transpose(...), img)' to obtain other axes...

Julien Lhermitte

unread,
May 23, 2015, 1:44:21 AM5/23/15
to pyqt...@googlegroups.com
I see. I just took a look at the code and I see that the axes parameter is not being forwarded, it is reset to (0,1)
You could actually confirm that this is the case by taking the transposed array like you said but changing the axes flag to different values and seeing that you still get the same result.

I'm not sure how often those that manage the source look at this forum but I also sent a pull request to attract attention.

This is a great library and think should be supported :-)

Julien Lhermitte

unread,
Aug 3, 2015, 10:08:05 PM8/3/15
to pyqtgraph
For the record, I switched to matplotlib. You have to add the zoom and pan with mouse functionality yourself but it's much more mature and there is more support. I'm sorry to say this.

L. Smash

unread,
Aug 5, 2015, 12:52:48 PM8/5/15
to pyqtgraph, jrmlhe...@gmail.com
Are there also methods to extract randomly drawn ROI's like e.g. a polygon? I found this example but I did not find a way to extract the whole region drawn with the lasso like with getArrayRegion in pyqtgraph?!

Julien Lhermitte

unread,
Aug 5, 2015, 2:00:18 PM8/5/15
to pyqtgraph, jrmlhe...@gmail.com
Yes, "contains_points" is what you need. First, create a list of all points in the image (no syntax highlighting because google's syntax highlighting seems buggy):
x = np.arange(self.xdim)
y = np.arange(self.ydim)
self.X,self.Y = np.meshgrid(x,y)
self.X = self.X.ravel()
self.Y = self.Y.ravel()
self.allpoints = np.transpose([np.transpose(self.X),np.transpose(self.Y)]) #create an [[x,y],...] pair array


Then find a way to grab your xs and ys (xs and ys are each arrays same length of x y coord).
Finally, use matplotlib.path.Path object to create a path from the points and check if they belong in the image:
self.polypath = Path(np.transpose([self.xs,self.ys]))
self.mtmp = self.polypath.contains_points(self.allpoints)
self.mtmp.shape = self.dims

I've attached rudimentary self-contained code. Feel free to check it out. To run, I recommend running it in ipython, including it and running:
from MaskCreator import MaskCreator
ion() #to keep the window from closing
a = MaskCreator() # will start the mask routine


Then mouse over, click "i" to include a region. Holding SHIFT+ click will create a region. Middle mouse button pans (by clicking) and zooms (scrolling mouse wheel).
The left click without shift is reserved to moving the ROI but I have not implemented this yet. Busy working on other stuff.

Honestly, I find this to be much better. On top of that, if I have a question, I can ask on a forum and I will get an answer from one of the developers who knows about it. The community is very active, and this is really a time saver.

Pyqtgraph was impressive with all the things it seemed to have that were convenient out of the box. However, once I needed a small customization, it was difficult to find help. It's kind of hard to start a developer community when the base developers can't even help you. If they want to improve, I suggest to the developers to try becoming more active in helping and also maybe acknowledge pull requests, then they may have more developers joining and helping the community. I tried one and gave up even reading the source code after I received no response.

I also haven't seen anything in pyqtgraph that I couldn't do in matplotlib yet.

Good luck! :-)
MaskCreator.py

Daniel Lidstrom

unread,
Aug 6, 2015, 6:42:32 PM8/6/15
to pyqtgraph, jrmlhe...@gmail.com
I doubt the author would entirely disagree.  From the front page of the pyqtgraph website:

Comparison to other python graphics packages:

Matplotlib is more or less the de-facto standard plotting library for python. If you are starting a new project and do not need any of the features specifically provided by pyqtgraph, you should start with matplotlib. It is much more mature, has an enormous user community, and produces very nice publication-quality graphics.

Reasons you might want to use pyqtgraph instead:

  1. Speed. If you are doing anything requiring rapid plot updates, video, or realtime interactivity, matplotlib is not the best choice. This is (in my opinion) matplotlib's greatest weakness.
  2. Portability / ease of installation. PyQtGraph is a pure-python package, which means that it runs on virtually every platform supported by numpy and PyQt, no compiling required. If you require portability in your application, this can make your life a lot easier.
  3. Many other features--pyqtgraph is much more than a plotting library; it strives to cover many aspects of science/engineering application development with more advanced features like its ImageView and ScatterPlotWidget analysis tools, ROI-based data slicing, parameter trees, flowcharts, multiprocessing, and more.
In my case, I started out with matplotlib, but had to switch over to pyqtgraph due to a need for realtime interactivity with large amounts of data.  I found matplotlib to be unusably slow for this.  So sure pyqtgraph has its weaknesses, but for some people (like me), it's indispensable.
Reply all
Reply to author
Forward
0 new messages