Closed jarmarshall closed 5 years ago
Duplicate of #9
@jarmarshall, I thought you were looking into this
I have started something and will hand over to you shortly...
@joefresna please switch to branch export-data
where I have modified downloadTimeEvolution()
in MuMoTmultiagentController
to use a Qt file dialog - due to an apparent bug in PyQt5, at least on OS X, I have had to use the non-native version of the dialog. The selected file is then written into with a test message. It remains to be seen how this works on MyBinder - hopefully the user's local filesystem will be accessible.
I think now you should be able to write your simulation data into this file in an appropriate format. As I assume MuMoTSSAView
also uses the same data structure I think the relevant methods should be moved up to MuMoTstochasticSimulationView
from where they will be inherited by all child classes. Then we just need to add this to the documentation (issue #139 already updated).
The branch export-data
does not work for me...
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-4d2bf7b6699e> in <module>
----> 1 import mumot
2 mumot.about()
3 mumot.setVerboseExceptions(True)
~/MuMoT/mumot/__init__.py in <module>
34 matplotlib.use('TkAgg')
35
---> 36 from PyQt5 import QtGui
37 from PyQt5 import QtGui, QtWidgets
38 import ipywidgets.widgets as widgets
ModuleNotFoundError: No module named 'PyQt5'
about the formatting, you can try this (should work):
f = open(fname[0], 'w')
line = 'runID' + '\t' + 'time'
for state in sorted(self._view._initialState.keys(), key=str):
line += '\t' + str(state)
line += '\n'
f.write(line)
for runID,runData in enumerate(self._view._latestResults):
line = str(runID) + '\t' + runData['time']
for state in sorted(self._view._initialState.keys(), key=str):
if state in self._mumotModel._constantReactants: continue
line += '\t' + str(runData[state])
line += '\n'
f.write(line)
f.close()
and also I would move the function downloadTimeEvolution()
into the MuMoTstochasticSimulationController()
parent class.
I recommend using a context manager (the 'with' keyword) when reading/writing files.
I updated setup.py
to include the requirement for pyqt
in branch export-data
- for now I pinned this to 5.6.0, which works for me, in case of any dependency side-effects by going for any other version; but probably this can be relaxed later. @joefresna can you see if this works for you? I suggest you follow @willfurnass suggestion to use a context manager in your implementation; these are used elsewhere in the code.
I pulled the new setup.py
, generated a new environment and followed the installation steps.
The pip installation does not work, I get this error:
$$ python -m pip install /Users/joefresna/MuMoT
Processing /Users/joefresna/MuMoT
Collecting antlr4-python3-runtime==4.5.3 (from mumot==0.1.0.dev0)
Collecting graphviz (from mumot==0.1.0.dev0)
Using cached https://files.pythonhosted.org/packages/1f/e2/ef2581b5b86625657afd32030f90cf2717456c1d2b711ba074bf007c0f1a/graphviz-0.10.1-py2.py3-none-any.whl
Collecting ipykernel<4.7 (from mumot==0.1.0.dev0)
Using cached https://files.pythonhosted.org/packages/18/c3/76775a650cae2e3d9c033b26153583e61282692d9a3af12a3022d8f0cefa/ipykernel-4.6.1-py3-none-any.whl
Collecting ipython (from mumot==0.1.0.dev0)
Downloading https://files.pythonhosted.org/packages/14/3b/3fcf422a99a04ee493e6a4fc3014e3c8ff484a7feed238fef68bdc285085/ipython-7.3.0-py3-none-any.whl (768kB)
100% |████████████████████████████████| 778kB 1.9MB/s
Collecting ipywidgets (from mumot==0.1.0.dev0)
Using cached https://files.pythonhosted.org/packages/30/9a/a008c7b1183fac9e52066d80a379b3c64eab535bd9d86cdc29a0b766fd82/ipywidgets-7.4.2-py2.py3-none-any.whl
Collecting matplotlib<3.0 (from mumot==0.1.0.dev0)
Downloading https://files.pythonhosted.org/packages/55/bf/cb625a3050c444da570541d33f51c3640d34a34a6f593bc7780deb97b4ec/matplotlib-2.2.4-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (14.0MB)
100% |████████████████████████████████| 14.0MB 1.8MB/s
Collecting networkx (from mumot==0.1.0.dev0)
Collecting notebook<5.5 (from mumot==0.1.0.dev0)
Using cached https://files.pythonhosted.org/packages/96/1f/e113875e6b8c8ee0e8c5748bf6fc942a109874adc9ca25248e95cf069803/notebook-5.4.1-py2.py3-none-any.whl
Collecting pydstool (from mumot==0.1.0.dev0)
Collecting pyqt==5.6.0 (from mumot==0.1.0.dev0)
Could not find a version that satisfies the requirement pyqt==5.6.0 (from mumot==0.1.0.dev0) (from versions: )
No matching distribution found for pyqt==5.6.0 (from mumot==0.1.0.dev0)
@jarmarshall , did the installation work for you?
just tried also with pyqt5==5.6.0
but it says:
Could not find a version that satisfies the requirement pyqt5==5.6.0 (from mumot==0.1.0.dev0) (from versions: 5.7.1, 5.8, 5.8.1.1, 5.8.2, 5.9, 5.9.1, 5.9.2, 5.10, 5.10.1, 5.11.2, 5.11.3, 5.12)
Didn’t have time to try it (and I am a bit lost with the installation process now - this seemed the only place to put this). Maybe @willfurnass can advise... I believe I had version 5.6.0 installed though...
Why is Qt needed? To provide a file download dialog? Could you eliminate this dependency if you use tkinter instead of PyQt5?
Might be useful: https://pythonspot.com/tk-file-dialogs/
Thanks @willfurnass - that looked promising, but just trying the code snippet at the link you shared reliably caused my kernel to die on OS X. This was a problem I also had with Qt, and had to tweak the code for that, so maybe it could be made to work. But it may be more straightforward to fix the qt dependency. Is there a reason to prefer tk over qt?
tkinter is bundled with Python:
>>> import tkinter
>>> tkinter.__file__
'/usr/lib64/python3.7/tkinter/__init__.py'
Unfortunately if it doesn't work, being bundled doesn't help...
Do you have a minimal failing example with tkinter
?
The one you linked to ;)
from tkinter import filedialog
from tkinter import *
root = Tk()
root.filename = filedialog.asksaveasfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
print (root.filename)
Ah, yes, this won't work if using a remote server. How about the following?
from IPython.display import HTML
import base64
def create_download_link(text, title="Download file", filename="file.txt"):
b64 = base64.b64encode(text.encode())
payload = b64.decode()
html = '<a download="{filename}" href="data:text/text;base64,{payload}" target="_blank">{title}</a>'
html = html.format(payload=payload,title=title,filename=filename)
return HTML(html)
create_download_link("some text here")
(inspired by https://medium.com/ibm-data-science-experience/how-to-upload-download-files-to-from-notebook-in-my-local-machine-6a4e65a15767)
Actually I was running the tkinter example on a localhost, on OS X.
I'd seen the display alternative, and it works, but I think it is quite ugly... I would rather get the Qt example working I think...
But tkinter or Qt will only work for local Jupyter servers for which $DISPLAY
references a local display.
Thanks @willfurnass
@joefresna I've reverted on branch export-data to remove the additional, now unnecessary, requirement. Please can you pull that and try Will's proposed solution for downloading your log files?
@joefresna N.B it might be simplest to start a completely new branch, since the beginning of the export-data
branch simply introduced the now redundant Qt approach, and that branch is now behind master by some way...
Thanks, @willfurnass , your solution worked great. The pending pull request #303 will implement this functionality
Suggest a method
saveSimulationData(<filename>)
- need to figure out how to access local filespace, and what to do if no argument is provided (open a dialog?)