From: Benjamin R. <ben...@ou...> - 2015-04-29 13:46:48
|
Here is a proof of concept (yes, it uses qt4... my work computer doesn't have qt5, but that should be a straight-forward modification to make). Note the complete lack of any call to mouse_init() and the complete lack of any use of pyplot (in fact, I commented it out to make the point that you shouldn't use pyplot *at all* when doing this sort of embedding). ``` import numpy as np #import matplotlib.pyplot as plt import sys from matplotlib.backends.qt4_compat import QtGui, QtCore from matplotlib.figure import Figure from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from mpl_toolkits.mplot3d import Axes3D if __name__ == '__main__': # Must come before any Qt widgets are made app = QtGui.QApplication(sys.argv) win = QtGui.QMainWindow() fig = Figure() canvas = FigureCanvas(fig) ax = fig.add_subplot(1, 1, 1, projection='3d') xs = np.random.rand(25) ys = np.random.rand(25) zs = np.random.rand(25) ax.scatter(xs, ys, zs) win.resize(int(fig.bbox.width), int(fig.bbox.height)) win.setWindowTitle("Embedding with Qt") # Needed for keyboard events canvas.setFocusPolicy(QtCore.Qt.StrongFocus) canvas.setFocus() win.setCentralWidget(canvas) win.show() sys.exit(app.exec_()) ``` I hope this helps! Ben Root On Wed, Apr 29, 2015 at 5:38 AM, Christian Ambros <am...@ym...> wrote: > Ok, back from revision... > > The is no mix-up for the show command. The only explicit show() command is > commented out in line 41. It can be deleted. But I haven't done that, yet. > There are several bits of code which are remains of the design process > since this is work in progress. Code cleaning will be done when the main > functionality is in place. > > Back to addmpl where I embedded gui elements into the canvas. Taking out > the matplotlib taskbar doesn't change a thing as I wrote earlier, but to > make sure it doesn't bother the mainloop, it should be commented out. I may > not put it back in, because I don't see the point in needing it. It was > just to see if it's possible. > > >>But option 2 relinquishes that control to the developer's GUI app. You > *cannot* use pyplot for option 2, which is what you are doing. > > Is that so? In line 116 I create the canvas, which is derived from > matplotlib's backend's FigureCanvasQTAgg and given to the QWidget at line > 119. That's the only part where both interact with each other. the rest is > handle by matplotlib. > > The error message says that Axes3D.figure.canvas is 'None' and that's why > mouse rotation is disabled. > It's None because there is no content at that point, when it's passed to > the QWidget. It's filled with content in line 38. So if matplotlib disables > the mouse rotation by default, when the canvas is empty how do I prevent > this disabling by default? > If I can't, at what point do I have to pass the filled canvas to the > QWidget? How does that impact the GUI itself? > If I can't enable the mouse rotation by hand and I just can pass filled > canvas around, do I have to build a work around with initialize it with an > empty 2D canvas and replace it later with the filled 3D canvas? How's the > mouse rotation activated then? > > In general, I wouldn't have to enable the rotation if it wouldn't be > switch off for an empty canvas. > > I'm going to consult your book, now, for different ways of coping with > such things... > > cheers, > Christian > > -- > "A little learning never caused anyone's head to explode!" > > > "Ein wenig Lernen hat noch niemandens Kopf zum Explodieren gebracht!" > > > > On Tuesday, April 28, 2015 8:28 PM, Benjamin Root <ben...@ou...> > wrote: > > > One thing I see off the bat is your addmpl() method: > > ``` > def addmpl(self, fig): > #FigureCanvas.__init__(self, fig) > self.canvas = FigureCanvas(fig) > > Axes3D.mouse_init(self, rotate_btn=1, zoom_btn=2) > self.mplvl.addWidget(self.canvas) > self.canvas.draw() > self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, > coordinates=True) > self.mplvl.addWidget(self.toolbar) > ``` > > You are calling Axes3D.mouse_init() on the Main object (that is `self`). > That is completely wrong. It can only be called for the 3d axes objects. > > Also, what I see happening here is some mixing up of how to do embedding. > There are two approaches to embedding. 1) you can embedded GUI elements > into your canvas widget, or 2) you can embed your canvas widget into your > GUI app. The important distinction between the two is who controls the > mainloop. In option 1 (and in matplotlib in general), pyplot will create > the GUI app for you automatically (it is completely transparent to you) and > kicks it off upon call to show(). But option 2 relinquishes that control to > the developer's GUI app. You *cannot* use pyplot for option 2, which is > what you are doing. Rip out all of the pyplot stuff, and instantiate the > Qt5 Figure object directly, and then obtain the axes objects from the > figure object via calls to add_subplot(). You shouldn't even need to do the > whole mouse_init() stuff. > > I now think this has nothing to do with Qt Designer. While I don't > specifically cover qt5 in my book, I do make all of these distinctions very > clear in chapter 5 of my book "Interactive Applications using Matplotlib". > > Cheers! > Ben Root > > > On Tue, Apr 28, 2015 at 4:03 PM, Christian Ambros <am...@ym...> > wrote: > > Hi Benjamin, > > I would do that if my task were my private stuff, but in this case it's > work-related and my boss wants me to use the designer and he already set a > deadline, which, I already knew, is set to tight. I told him before, that > it would be just a try but he sold it to his boss after some pressure. You > know how the bosses' bosses are, they don't get the idea that innovation > can't be dictated. They don't understand the concept that software is > written and doesn't come into existence out of nothing. > > Without PyQt5 it's working fine. I got the plots and they are gorgeous, > but that doesn't help when presenting to the bosses. If I just would know > how to activate the 3d-draw's mouse action again, by hand, than it has to > last just some moments for the presentation, afterwards I have the time to > examine and find a more robust solution. > > Thanks for the effort. > cheers, > Christian > > -- > "A little learning never caused anyone's head to explode!" > > > "Ein wenig Lernen hat noch niemandens Kopf zum Explodieren gebracht!" > > > > On Tuesday, April 28, 2015 7:30 PM, Benjamin Root <ben...@ou...> > wrote: > > > I think there is something wrong with the embedding code rather than there > being an actual bug. I have embedded mplot3d stuff before (admittedly, not > in qt5) with no problems. I haven't had the time yet to examine your code > to see what the potential issue is, though. I have also never used Qt > designer, so I have no clue if there is something that it is doing that > might be making things difficult. > > I already know that the code you originally posted has errors in it. I > would suggest first making a prototype without Qt Designer as a > proof-of-concept, perhaps starting with one of our examples in the gallery? > > Ben Root > > > On Tue, Apr 28, 2015 at 2:12 PM, Christian Ambros <am...@ym...> > wrote: > > Since there seems to be no progress with this issue, may I assume there > isn't any interest in it? > I took a further look around in the internet but couldn't any solution. > It leads to an other question: How many users of matplotlib are using > 3d-plots anyway? It we are just a few and there won't be anyone who wants > to embed it in PyQt5, than I can understand that this issue doesn't concern > no-one and I have to look somewhere else to find a 3d-plotting lib which is > embedable. > > cheers, > Christain > -- > "A little learning never caused anyone's head to explode!" > > > "Ein wenig Lernen hat noch niemandens Kopf zum Explodieren gebracht!" > > > > On Tuesday, April 21, 2015 1:44 PM, Benjamin Root <ben...@ou...> > wrote: > > > The addmpl() method isn't right. You created a canvas object, assigned it > to self.canvas, but then tried to call FigureCanvas.__init__(), passing it > whatever object "self" is. What class is addmpl() a part of? What does it > subclass? > > On Tue, Apr 21, 2015 at 7:24 AM, Christian Ambros <am...@ym...> > wrote: > > Hi, > > I embedded Ryan's examble for PyQt5-matplotlib use into my App but I get > the following error: > > /usr/local/lib/python3.4/dist-packages/mpl_toolkits/mplot3d/axes3d.py:1009: > UserWarning: Axes3D.figure.canvas is 'None', mouse rotation disabled. Set > canvas then call Axes3D.mouse_init(). > warnings.warn('Axes3D.figure.canvas is \'None\', mouse rotation > disabled. Set canvas then call Axes3D.mouse_init().') > > From Stackoverflow, which host to question about this, I know that mouse > actions are disabled when the canvas is re-initialized by whatever. > > The only position I do such an operation is in here: > > > > > > > > *def addmpl(self, fig): self.canvas = FigureCanvas(fig) > #FigureCanvas.__init__(self, fig) #Axes3D.mouse_init(self) > self.mplvl.addWidget(self.canvas) self.canvas.draw() > self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, > coordinates=True) self.mplvl.addWidget(self.toolbar)* > > On of the Stackoverflow suggestion says, that re initializing FigureCanvas > should do the trick but I'll get: > > Traceback (most recent call last): > File "./ex_0.1.py", line 145, in <module> > main(sys.argv) > File "./ex_0.1.py", line 53, in main > mainwindow.addmpl(fig1) > File "./ex_0.1.py", line 116, in addmpl > FigureCanvas.__init__(self, fig) > File > "/usr/local/lib/python3.4/dist-packages/matplotlib/backends/backend_qt5agg.py", > line 181, in __init__ > FigureCanvasQT.__init__(self, figure) > File > "/usr/local/lib/python3.4/dist-packages/matplotlib/backends/backend_qt5.py", > line 237, in __init__ > super(FigureCanvasQT, self).__init__(figure=figure) > TypeError: super(type, obj): obj must be an instance or subtype of type > > as follow-up error message. > > just using *Axes3D.mouse_init()* , as suggested by matplotlib itself, > leads to: > > Traceback (most recent call last): > File "./ex_0.1.py", line 146, in <module> > main(sys.argv) > File "./ex_0.1.py", line 53, in main > mainwindow.addmpl(fig1) > File "./ex_0.1.py", line 118, in addmpl > Axes3D.mouse_init() > TypeError: mouse_init() missing 1 required positional argument: 'self' > > adding self leads to: > > Traceback (most recent call last): > File "./ex_0.1.py", line 146, in <module> > main(sys.argv) > File "./ex_0.1.py", line 53, in main > mainwindow.addmpl(fig1) > File "./ex_0.1.py", line 118, in addmpl > Axes3D.mouse_init(self) > File > "/usr/local/lib/python3.4/dist-packages/mpl_toolkits/mplot3d/axes3d.py", > line 1002, in mouse_init > canv = self.figure.canvas > AttributeError: 'Main' object has no attribute 'figure' > ./ex_0.1.py & > > Maybe I'm adding those lines at the wrong place, but I could fined > anything useful in the matplotlib documantation, that would help me out, > either. > > Any thougts that might help? > > Cheers, > Christian > > -- > "A little learning never caused anyone's head to explode!" > > > "Ein wenig Lernen hat noch niemandens Kopf zum Explodieren gebracht!" > > > ------------------------------------------------------------------------------ > BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT > Develop your own process in accordance with the BPMN 2 standard > Learn Process modeling best practices with Bonita BPM through live > exercises > http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- > event?utm_ > source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > > > > > > > ------------------------------------------------------------------------------ > One dashboard for servers and applications across Physical-Virtual-Cloud > Widest out-of-the-box monitoring support with 50+ applications > Performance metrics, stats and reports that give you Actionable Insights > Deep dive visibility with transaction tracing using APM Insight. > http://ad.doubleclick.net/ddm/clk/290420510;117567292;y > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > > > > > > > > |