emdgroup / baybe

Bayesian Optimization and Design of Experiments
https://emdgroup.github.io/baybe/
Apache License 2.0
212 stars 34 forks source link

invalid command name ".!canvas" when using plotting utils #284

Open sgbaird opened 1 week ago

sgbaird commented 1 week ago

When running https://github.com/emdgroup/baybe/blob/main/examples/Transfer_Learning/basic_transfer_learning.py locally (pip install -e .[dev], Windows 11, Python 3.11.*), I get the following error:

Exception has occurred: TclError       (note: full exception trace is shown but execution is paused at: _run_module_as_main)
invalid command name ".!canvas"
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\tkinter\__init__.py", line 1711, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\tkinter\__init__.py", line 1721, in configure
    return self._configure('configure', cnf, kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\site-packages\matplotlib\backends\_backend_tk.py", line 543, in resize
    self.canvas._tkcanvas.configure(width=width, height=height)
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\site-packages\matplotlib\figure.py", line 3045, in set_size_inches
    manager.resize(*(size * self.dpi).astype(int))
  File "C:\Users\sterg\Documents\GitHub\sgbaird\baybe\baybe\utils\plotting.py", line 107, in create_example_plots
    ax.figure.set_size_inches(*figsize)
  File "C:\Users\sterg\Documents\GitHub\sgbaird\baybe\examples\Transfer_Learning\basic_transfer_learning.py", line 177, in <module>
    create_example_plots(
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
  File "C:\Users\sterg\miniforge3\envs\baybe\Lib\runpy.py", line 198, in _run_module_as_main (Current frame)
    return _run_code(code, main_globals, None,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: invalid command name ".!canvas"

Related: https://stackoverflow.com/questions/45508038/invalid-command-name-canvas

Maybe because I'm running it as a script rather than within a notebook environment.

xref: https://github.com/emdgroup/baybe/discussions/283

AdrianSosic commented 1 week ago

Hi @sgbaird, thanks for the report. We haven't had much interaction with Windows so far, so no surprise there are some unexpected things happening. The good news, though: this one here is only related to plotting and quite certainly a matplotlib backend issue. So to unblock your work, you can simply skip the create_example_plots call in the example and display the figure yourself (the call is anyway just to produce the plots shown in the docs).

Can you do me a favor and tell me what import matplotlib; print(matplotlib.get_backend()) gives you?

sgbaird commented 1 week ago

Hi @sgbaird, thanks for the report. We haven't had much interaction with Windows so far, so no surprise there are some unexpected things happening. The good news, though: this one here is only related to plotting and quite certainly a matplotlib backend issue. So to unblock your work, you can simply skip the create_example_plots call in the example and display the figure yourself (the call is anyway just to produce the plots shown in the docs).

Makes sense!

Can you do me a favor and tell me what import matplotlib; print(matplotlib.get_backend()) gives you?

tkagg

sgbaird commented 1 week ago

@mehradans92 brought up with me for the cluster experiment notebook that changing path = "." fixed the issue. Simple cross-platform fix:

# Check operating system and set path accordingly
if os.name == "nt":  # Windows
    path = "."
else:  # Linux and others
    path = Path(sys.path[0])
...
create_example_plots(
    ax=ax,
    path=path,
    base_name="basic_transfer_learning",
)

Feel free to close.

AdrianSosic commented 1 week ago

Ok, thanks for the info. We should nevertheless implement a fix on our side as well.

@sgbaird: Can you tell us what print(sys.path) actually gives you? @AVHopp: I guess you had a reason why you went via path = Path(sys.path[0]). Can you elaborate / do you have an idea how to make it cross-platform compatible?

mehradans92 commented 1 week ago

@AdrianSosic PosixPath('/home/mehrad/anaconda3/envs/baybe/lib/python311.zip') Not sure where the .zip is coming from. I am on WSL btw, which shouldn't really change things much.

AVHopp commented 1 week ago

@AdrianSosic If I remember correctly, that was one of the issues with making sure that the files are executable after being transformed into a notebook - it was a quite a pain to figure out how to set paths such that stuff works after the conversion without having to either make the examples complex/introduce custom code for that only. I unfortunately do not see an easy way to make this cross-platform compatible without any compromise. The easiest way would probably to just add an explanation and a comment with different code?

AVHopp commented 1 week ago

I have opened a Pull Request #288 for changing this. From my current tests, it seems like choosing "." also works in our pipeline and when automatically converting the python files to notebooks. Will investigate further.

EDIT: I checked again: The reason for this choice was that this guarantees that the created images are placed in the folder in which the file is located - independent on whether it is executed as a .py file or converted into a notebook first. If I remember correctly, this was at some point necessary due to our automated checks. I am however unsure if this is still necessary and will investigate.