spyder-ide / spyder

Official repository for Spyder - The Scientific Python Development Environment
https://www.spyder-ide.org
MIT License
8.29k stars 1.61k forks source link

Error opening 3-D NumPy Masked Array in variable explorer window #16796

Open darwin-cai opened 2 years ago

darwin-cai commented 2 years ago

Description

What steps will reproduce the problem?

Error description

Spyder version: 5.1.5 Python 3.8 I want to open a masked 3-D NumPy Array in the variable explorer window, but Spyder prompts an error message, Inner Error. In the previous version of Spyder (e.g., 5.0.5), a masked 3-D array can be opened.

Traceback

Traceback (most recent call last):
  File "D:\ProgramData\Anaconda3\lib\site-packages\spyder\plugins\variableexplorer\widgets\collectionsdelegate.py", line 176, in createEditor
    if not editor.setup_and_check(value, title=key, readonly=readonly):
  File "D:\ProgramData\Anaconda3\lib\site-packages\spyder\plugins\variableexplorer\widgets\arrayeditor.py", line 772, in setup_and_check
    btn_layout_top.addWidget(self.shape_label)
AttributeError: 'ArrayEditor' object has no attribute 'shape_label'

Versions

Dependencies


# Mandatory:
atomicwrites >=1.2.0          :  1.4.0 (OK)
chardet >=2.0.0               :  4.0.0 (OK)
cloudpickle >=0.5.0           :  2.0.0 (OK)
cookiecutter >=1.6.0          :  1.7.2 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.1.0 (OK)
IPython >=7.6.0               :  7.29.0 (OK)
jedi >=0.17.2;<0.19.0         :  0.18.0 (OK)
jsonschema >=3.2.0            :  3.2.0 (OK)
keyring >=17.0.0              :  23.1.0 (OK)
nbconvert >=4.0               :  6.1.0 (OK)
numpydoc >=0.6.0              :  1.1.0 (OK)
paramiko >=2.4.0              :  2.7.2 (OK)
parso >=0.7.0;<0.9.0          :  0.8.2 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.8.0 (OK)
pygments >=2.0                :  2.10.0 (OK)
pylint >=2.5.0;<2.10.0        :  2.9.6 (OK)
pyls_spyder >=0.4.0           :  0.4.0 (OK)
pylsp >=1.2.2;<1.3.0          :  1.2.4 (OK)
pylsp_black >=1.0.0           :  None (OK)
qdarkstyle =3.0.2             :  3.0.2 (OK)
qstylizer >=0.1.10            :  0.1.10 (OK)
qtawesome >=1.0.2             :  1.0.2 (OK)
qtconsole >=5.1.0             :  5.1.1 (OK)
qtpy >=1.5.0                  :  1.10.0 (OK)
rtree >=0.9.7                 :  0.9.7 (OK)
setuptools >=49.6.0           :  58.0.4 (OK)
sphinx >=0.6.6                :  4.2.0 (OK)
spyder_kernels >=2.1.1;<2.2.0 :  2.1.3 (OK)
textdistance >=4.2.0          :  4.2.1 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3             :  2.1.3 (OK)
zmq >=17                      :  22.2.1 (OK)

# Optional:
cython >=0.21                 :  None (OK)
matplotlib >=2.0.0            :  3.4.1 (OK)
numpy >=1.7                   :  1.21.2 (OK)
pandas >=1.1.1                :  1.2.4 (OK)
scipy >=0.17.0                :  1.7.0 (OK)
sympy >=0.7.3                 :  None (OK)
darwin-cai commented 2 years ago

Problem solved

I have fixed the error by editing the source file "spyder/plugins/variableexplorer/widgets/arrayeditor.py" after line 718. After adding the code within elif data.ndim == 3: to elif is_masked_array:, detailed changes are as follows:

in script arrayeditor.py start line: 712

elif is_masked_array:
    self.stack.addWidget(ArrayEditorWidget(self, data, readonly,
                                                   xlabels, ylabels))
    self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly,
                                                   xlabels, ylabels))
    self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly,
                                                   xlabels, ylabels))
    #! -----------------modify start-----------------
    # QSpinBox
    self.index_spin = QSpinBox(self, keyboardTracking=False)
    self.index_spin.valueChanged.connect(self.change_active_widget)

    # Labels
    self.shape_label = QLabel()
    self.slicing_label = QLabel()

    # Set the widget to display when launched
    self.current_dim_changed(self.last_dim)
    #! -----------------modify end-----------------
elif data.ndim == 3:
    # We create here the necessary widgets for current_dim_changed to
    # work. The rest are created below.
    # QSpinBox
    self.index_spin = QSpinBox(self, keyboardTracking=False)
    --snip--
dalthviz commented 2 years ago

Hi @DeevenCai thank you for the feedback! Could you give an example code that triggers this error for you? Also, as you already implemented a fix for this, would you like to submit a PR with your proposed changes?

Just in case, if you want to submit your fix our contribution guide could help (https://github.com/spyder-ide/spyder/blob/5.x/CONTRIBUTING.md) using as base branch the 5.x branch. If you have any doubt let us know!

darwin-cai commented 2 years ago

Thanks for your @dalthviz response. The example code is as follows:

# -*- coding: utf-8 -*-
from netCDF4 import Dataset
ncfile = r'D:\Data\GLASS\GLASS10B02.FVC.1982.nc'
ncid = Dataset(ncfile, 'r')
months = ncid['time'][:]    # read time dimension
lon, lat = ncid['lon'][:], ncid['lat'][:]    # read longitude and latitude dimension
fvc = ncid['FVC'][:]    # read main variable data, which is a 3-Dim NumPy Masked Array, in dim (time, lat, lon)
ncid.close()    # close the handle

Then, the variable fvc is collected by the Variable Explorer Window of Spyder. I clicked fvc in the Variable explorer window to see what the data looks like, but the Error window was prompted as previously reported. So I checked the source code and modified some of them.

In later use of the Variable Explorer Window to show NumPy Masked Array, more errors occurred. I found that there are many bugs for showing masked array in the variable explorer window (an example given below), therefore, attention should be paid to such issues.


Bug Example

code file: spyder\plugins\variableexplorer\widgets\arrayeditor.py start line: 889 function: def current_dim_changed(self, index) error in line 895: string_size = ['%i']*3 correction: string_size = ['%i']*self.data.ndim


I think the dimensions should change with input arrays, not a fixed number 3. Similar errors may occur in lines 866, 874, I am not sure am I right.

As for contributing to Spyder, I can't do anything because I have no experience in software development. I am sorry for this. Thank you guys for your hard work to maintain Spyder.

dalthviz commented 2 years ago

Thank you @DeevenCai for the new info and the testing you did! Just in case, I was able to reproduce this with this code too:

import numpy as np

x = np.ma.array([[[1]], [[2]], [[3]]])
PlusUltra2021 commented 2 years ago

Thank you @DeevenCai, the 3-D masked array can be double-click-viewed after your modification in file "arrayeditor.py"! However, a side effect is that the 1-D & 2-D masked array CAN'T be viewed with a Spyder error popup . 😂 (And after I remove the modification and restart Spyder, the 1-D & 2-D masked array can be viewed like before.) Hope there to be a final solution to this~

dalthviz commented 2 years ago

Hi @PlusUltra2021 maybe you could try the solution at https://github.com/spyder-ide/spyder/pull/16919 . Let us know if that covers all the cases (1-D, 2-D, 3-D)