dean0x7d / pybinding

Scientific Python package for tight-binding calculations in solid state physics
https://pybinding.site
BSD 2-Clause "Simplified" License
185 stars 68 forks source link

pybinding returns an error for a 1D lattice defined by the book (literally) #50

Open rpoteau opened 8 months ago

rpoteau commented 8 months ago

Bert I am sorry to bother you again :-( I wanted to play with simple models, following the documentation to the letter. After graphene, I moved to a simple 1D lattice. Yet, the following piece of code gives an error message Could it be related to some issue in the development version? Best Romuald

import pybinding as pb import matplotlib.pyplot as plt

pb.pltutils.use_style()

def simple_chain_lattice(a=1, t=-1): """Very simple 1D lattice""" lat = pb.Lattice(a) lat.add_one_sublattice('A', [0, 0]) lat.add_one_hopping(1, 'A', 'A', t) return lat

model = pb.Model( simple_chain_lattice(), pb.line(-3.5, 3.5) # line start/end in nanometers ) model.plot() plt.show()

returns:


IndexError Traceback (most recent call last) Cell In[4], line 18 12 return lat 14 model = pb.Model( 15 simple_chain_lattice(), 16 pb.line(-3.5, 3.5) # line start/end in nanometers 17 ) ---> 18 model.plot() 19 plt.show()

File ~/Python3/ML/lib64/python3.11/site-packages/pybinding/model.py:172, in Model.plot(self, num_periods, lead_length, axes, kwargs) 170 for lead in self.leads: 171 lead.plot(lead_length, axes=axes, kwargs) --> 172 decorate_structure_plot(axes=axes)

File ~/Python3/ML/lib64/python3.11/site-packages/pybinding/system.py:246, in decorate_structure_plot(axes, addmargin, ax, **) 244 ax = plt.gca() 245 ax.set_aspect('equal') --> 246 ax.autoscale_view() 247 ax.set_xlabel("{} (nm)".format(axes[0])) 248 ax.set_ylabel("{} (nm)".format(axes[1]))

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axes/_base.py:2939, in _AxesBase.autoscale_view(self, tight, scalex, scaley) 2934 # End of definition of internal function 'handle_single_axis'. 2936 handle_single_axis( 2937 scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin, 2938 x_stickies, self.set_xbound) -> 2939 handle_single_axis( 2940 scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin, 2941 y_stickies, self.set_ybound)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axes/_base.py:2932, in _AxesBase.autoscale_view..handle_single_axis(scale, shared_axes, name, axis, margin, stickies, set_bound) 2929 x1 = min(x1, x1bound) 2931 if not self._tight: -> 2932 x0, x1 = locator.view_limits(x0, x1) 2933 set_bound(x0, x1)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2170, in MaxNLocator.view_limits(self, dmin, dmax) 2166 dmin, dmax = mtransforms.nonsingular( 2167 dmin, dmax, expander=1e-12, tiny=1e-13) 2169 if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers': -> 2170 return self._raw_ticks(dmin, dmax)[[0, -1]] 2171 else: 2172 return dmin, dmax

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2114, in MaxNLocator._raw_ticks(self, vmin, vmax) 2111 large_steps = large_steps & (floored_vmaxs >= _vmax) 2113 # Find index of smallest large step -> 2114 istep = np.nonzero(large_steps)[0][0] 2116 # Start at smallest of the steps greater than the raw step, and check 2117 # if it provides enough ticks. If not, work backwards through 2118 # smaller steps until one is found that provides enough ticks. 2119 for step in steps[:istep+1][::-1]:

IndexError: index 0 is out of bounds for axis 0 with size 0

Error in callback <function _draw_all_if_interactive at 0x7fe6bc615a80> (for post_execute), with arguments args (),kwargs {}:


IndexError Traceback (most recent call last) File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive() 195 def _draw_all_if_interactive() -> None: 196 if matplotlib.is_interactive(): --> 197 draw_all()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force) 130 for manager in cls.get_all_fig_managers(): 131 if force or manager.canvas.figure.stale: --> 132 manager.canvas.draw_idle()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, *kwargs) 1891 if not self._is_idle_drawing: 1892 with self._idle_draw_cntx(): -> 1893 self.draw(args, **kwargs)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self) 385 # Acquire a lock on the shared font cache. 386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar 387 else nullcontext()): --> 388 self.figure.draw(self.renderer) 389 # A GUI class may be need to update a window using this draw, so 390 # don't forget to call the superclass. 391 super().draw()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:95, in _finalize_rasterization..draw_wrapper(artist, renderer, *args, kwargs) 93 @wraps(draw) 94 def draw_wrapper(artist, renderer, *args, *kwargs): ---> 95 result = draw(artist, renderer, args, kwargs) 96 if renderer._rasterizing: 97 renderer.stop_rasterizing()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer) 3151 # ValueError can occur when resizing a window. 3153 self.patch.draw(renderer) -> 3154 mimage._draw_list_compositing_images( 3155 renderer, self, artists, self.suppressComposite) 3157 for sfig in self.subfigs: 3158 sfig.draw(renderer)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 130 if not_composite or not has_images: 131 for a in artists: --> 132 a.draw(renderer) 133 else: 134 # Composite any adjacent images together 135 image_group = []

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer) 3067 if artists_rasterized: 3068 _draw_rasterized(self.figure, artists_rasterized, renderer) -> 3070 mimage._draw_list_compositing_images( 3071 renderer, self, artists, self.figure.suppressComposite) 3073 renderer.close_group('axes') 3074 self.stale = False

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 130 if not_composite or not has_images: 131 for a in artists: --> 132 a.draw(renderer) 133 else: 134 # Composite any adjacent images together 135 image_group = []

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1387, in Axis.draw(self, renderer, *args, **kwargs) 1384 return 1385 renderer.open_group(name, gid=self.get_gid()) -> 1387 ticks_to_draw = self._update_ticks() 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer) 1390 for tick in ticks_to_draw:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1275, in Axis._update_ticks(self) 1270 def _update_ticks(self): 1271 """ 1272 Update ticks (position and labels) using the current data interval of 1273 the axes. Return the list of ticks that will be drawn. 1274 """ -> 1275 major_locs = self.get_majorticklocs() 1276 major_labels = self.major.formatter.format_ticks(major_locs) 1277 major_ticks = self.get_major_ticks(len(major_locs))

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1495, in Axis.get_majorticklocs(self) 1493 def get_majorticklocs(self): 1494 """Return this Axis' major tick locations in data coordinates.""" -> 1495 return self.major.locator()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2142, in MaxNLocator.call(self) 2140 def call(self): 2141 vmin, vmax = self.axis.get_view_interval() -> 2142 return self.tick_values(vmin, vmax)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2150, in MaxNLocator.tick_values(self, vmin, vmax) 2147 vmin = -vmax 2148 vmin, vmax = mtransforms.nonsingular( 2149 vmin, vmax, expander=1e-13, tiny=1e-14) -> 2150 locs = self._raw_ticks(vmin, vmax) 2152 prune = self._prune 2153 if prune == 'lower':

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2114, in MaxNLocator._raw_ticks(self, vmin, vmax) 2111 large_steps = large_steps & (floored_vmaxs >= _vmax) 2113 # Find index of smallest large step -> 2114 istep = np.nonzero(large_steps)[0][0] 2116 # Start at smallest of the steps greater than the raw step, and check 2117 # if it provides enough ticks. If not, work backwards through 2118 # smaller steps until one is found that provides enough ticks. 2119 for step in steps[:istep+1][::-1]:

IndexError: index 0 is out of bounds for axis 0 with size 0


IndexError Traceback (most recent call last) File ~/Python3/ML/lib/python3.11/site-packages/IPython/core/formatters.py:340, in BaseFormatter.call(self, obj) 338 pass 339 else: --> 340 return printer(obj) 341 # Finally look for special method names 342 method = get_real_method(obj, self.print_method)

File ~/Python3/ML/lib/python3.11/site-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, kwargs) 149 from matplotlib.backend_bases import FigureCanvasBase 150 FigureCanvasBase(fig) --> 152 fig.canvas.print_figure(bytes_io, kw) 153 data = bytes_io.getvalue() 154 if fmt == 'svg':

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs) 2161 # we do this instead of self.figure.draw_without_rendering 2162 # so that we can inject the orientation 2163 with getattr(renderer, "_draw_disabled", nullcontext)(): -> 2164 self.figure.draw(renderer) 2165 if bbox_inches: 2166 if bbox_inches == "tight":

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:95, in _finalize_rasterization..draw_wrapper(artist, renderer, *args, kwargs) 93 @wraps(draw) 94 def draw_wrapper(artist, renderer, *args, *kwargs): ---> 95 result = draw(artist, renderer, args, kwargs) 96 if renderer._rasterizing: 97 renderer.stop_rasterizing()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer) 3151 # ValueError can occur when resizing a window. 3153 self.patch.draw(renderer) -> 3154 mimage._draw_list_compositing_images( 3155 renderer, self, artists, self.suppressComposite) 3157 for sfig in self.subfigs: 3158 sfig.draw(renderer)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 130 if not_composite or not has_images: 131 for a in artists: --> 132 a.draw(renderer) 133 else: 134 # Composite any adjacent images together 135 image_group = []

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer) 3067 if artists_rasterized: 3068 _draw_rasterized(self.figure, artists_rasterized, renderer) -> 3070 mimage._draw_list_compositing_images( 3071 renderer, self, artists, self.figure.suppressComposite) 3073 renderer.close_group('axes') 3074 self.stale = False

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite) 130 if not_composite or not has_images: 131 for a in artists: --> 132 a.draw(renderer) 133 else: 134 # Composite any adjacent images together 135 image_group = []

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/artist.py:72, in allow_rasterization..draw_wrapper(artist, renderer) 69 if artist.get_agg_filter() is not None: 70 renderer.start_filter() ---> 72 return draw(artist, renderer) 73 finally: 74 if artist.get_agg_filter() is not None:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1387, in Axis.draw(self, renderer, *args, **kwargs) 1384 return 1385 renderer.open_group(name, gid=self.get_gid()) -> 1387 ticks_to_draw = self._update_ticks() 1388 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer) 1390 for tick in ticks_to_draw:

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1275, in Axis._update_ticks(self) 1270 def _update_ticks(self): 1271 """ 1272 Update ticks (position and labels) using the current data interval of 1273 the axes. Return the list of ticks that will be drawn. 1274 """ -> 1275 major_locs = self.get_majorticklocs() 1276 major_labels = self.major.formatter.format_ticks(major_locs) 1277 major_ticks = self.get_major_ticks(len(major_locs))

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/axis.py:1495, in Axis.get_majorticklocs(self) 1493 def get_majorticklocs(self): 1494 """Return this Axis' major tick locations in data coordinates.""" -> 1495 return self.major.locator()

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2142, in MaxNLocator.call(self) 2140 def call(self): 2141 vmin, vmax = self.axis.get_view_interval() -> 2142 return self.tick_values(vmin, vmax)

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2150, in MaxNLocator.tick_values(self, vmin, vmax) 2147 vmin = -vmax 2148 vmin, vmax = mtransforms.nonsingular( 2149 vmin, vmax, expander=1e-13, tiny=1e-14) -> 2150 locs = self._raw_ticks(vmin, vmax) 2152 prune = self._prune 2153 if prune == 'lower':

File ~/Python3/ML/lib64/python3.11/site-packages/matplotlib/ticker.py:2114, in MaxNLocator._raw_ticks(self, vmin, vmax) 2111 large_steps = large_steps & (floored_vmaxs >= _vmax) 2113 # Find index of smallest large step -> 2114 istep = np.nonzero(large_steps)[0][0] 2116 # Start at smallest of the steps greater than the raw step, and check 2117 # if it provides enough ticks. If not, work backwards through 2118 # smaller steps until one is found that provides enough ticks. 2119 for step in steps[:istep+1][::-1]:

IndexError: index 0 is out of bounds for axis 0 with size 0

<Figure size 544x467.2 with 1 Axes>

BertJorissen commented 7 months ago

Hi Romuald it seems that it didn't get notified about your question. This is actually a matplotlib bug, downgrading to an earlier matplotlib version will solve this. I'll try to fix it in a new release. I'll see what version gives the breaking code you mentioned above. Best Bert