DanPorter / Dans_Diffraction

Reads crystallographic cif files and simulates diffraction
Apache License 2.0
45 stars 13 forks source link

Error for plotting arrows with recent matplotlib #10

Closed asteppke closed 1 year ago

asteppke commented 1 year ago

Hello @DanPorter thank you for this great diffraction package!

I just discovered it and wanted to run the examples but unfortunately ran into trouble with plotting arrows:

C:\Dans_Diffraction> ipython example_build_crystal.py

###########################################
Oh! What a Lovely Crystal
Formula: NaO
Magnetic: False
a =  2.800 A,  b =  2.800 A,  c =  6.000 A
A =    90.00,  B =    90.00,  G =    90.00
Volume:  47.04 A^3

Density:  2.753 g/cm
  n Label Atom  u       v       w        Occ  Uiso
  0   Na1   Na  0.0000  0.0000  0.0000   1.00 0.0127
  1   Na1   Na  0.0000  0.0000  0.5000   1.00 0.0127
  2    O1    O  0.5000  0.5000  0.2500   1.00 0.0127
  3    O1    O  0.5000  0.5000  0.7500   1.00 0.0127

C:\Users\Alexander\Dropbox\dev\xray\Dans_Diffraction\Examples\..\Dans_Diffraction\classes_plotting.py:106: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
  ax.scatter(xyz[iii, 0], xyz[iii, 1], xyz[iii, 2], s=2 * sizes[n], c=col, label=labels[n], cmap=colors)
Traceback (most recent call last):
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\backends\backend_qt.py", line 468, in _draw_idle
    self.draw()
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\backends\backend_agg.py", line 400, in draw
    self.figure.draw(self.renderer)
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\artist.py", line 95, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\figure.py", line 3140, in draw
    mimage._draw_list_compositing_images(
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\matplotlib\artist.py", line 72, in draw_wrapper
    return draw(artist, renderer)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 471, in draw
    for artist in sorted(collections_and_patches,
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\tools\miniconda3\envs\jupyter\Lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 472, in <lambda>
    key=lambda artist: artist.do_3d_projection(),
                       ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Arrow3D' object has no attribute 'do_3d_projection'

It seems that the matplotlib people changed their api a bit for versions 3.5.0 and higher. I made a small change that should adapt to this different upstream api and here (python 3.11, matplotlib 3.7.1 on Windows 11) it seems to fix the issue nicely.

DanPorter commented 1 year ago

Thank you very much @asteppke for your interest and for pointing out this bug. Thanks also for suggesting the fix. I've merged this into the main branch now. I need to do some further testing across different matplotlib versions as it looks like the arrows don't show up any more in older version... I'll see if there is a solution that covers both otherwise I'll update the requirements for matplotlib > 3.5.