From: Fernando P. <fpe...@gm...> - 2012-01-29 09:12:31
|
Hi all, in ipython for the qtconsole and notebook, we send inline figures using fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight') as seen here: https://github.com/ipython/ipython/blob/master/IPython/core/pylabtools.py#L104 However, this produces truncated figure titles. Consider this code: f, ax = plt.subplots() ax.plot(rand(100)) ax.set_title('Axis title') f.suptitle('Figure title'); ### which produces this in the notebook: http://img546.imageshack.us/img546/5448/selection001c.png As you can see, the figure title gets truncated. We started using bbox_inches='tight' because otherwise in many cases the images were coming back with insane amounts of white padding, and Stefan vdW suggested this fix. But it seems that in other cases it actually loses data, which is even worse... A slightly more complicated example, using basemap, not only truncates the title but also all the x and y labels: from mpl_toolkits.basemap import Basemap lon0, lat0, lon1, lat1 = (84.38, 26.22, 88.9, 29.8) resolution = 'i' parallels = np.linspace(lat0, lat1, 5) meridians = np.linspace(lon0, lon1, 5) f, ax = plt.subplots() m = Basemap(lon0, lat0, lon1, lat1, resolution=resolution, ax=ax) m.drawcountries(color=(1,1,0)) # country boundaries in pure yellow m.drawrivers(color=(0,1,1)) # rivers in cyan m.bluemarble() # NASA bluemarble image m.drawmeridians(meridians, labels=[0,0,0,1], fmt='%.2f') m.drawparallels(parallels, labels=[1,0,0,0], fmt='%.2f') f.suptitle('The Himalayas'); ##### produces: http://img192.imageshack.us/img192/986/selection002e.png This looks like a matplotlib bug, but I have no idea how easy it is to fix. In the meantime, should we in ipython just revert back to not using bbox_inches, or is there an alternative? Thanks! f |
From: Benjamin R. <ben...@ou...> - 2012-01-29 15:42:44
|
On Sunday, January 29, 2012, Fernando Perez <fpe...@gm...> wrote: > Hi all, > > in ipython for the qtconsole and notebook, we send inline figures using > > fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight') > > as seen here: > > https://github.com/ipython/ipython/blob/master/IPython/core/pylabtools.py#L104 > > However, this produces truncated figure titles. Consider this code: > > f, ax = plt.subplots() > ax.plot(rand(100)) > ax.set_title('Axis title') > f.suptitle('Figure title'); > > ### > > which produces this in the notebook: > > http://img546.imageshack.us/img546/5448/selection001c.png > > As you can see, the figure title gets truncated. > > We started using bbox_inches='tight' because otherwise in many cases > the images were coming back with insane amounts of white padding, and > Stefan vdW suggested this fix. But it seems that in other cases it > actually loses data, which is even worse... > > A slightly more complicated example, using basemap, not only truncates > the title but also all the x and y labels: > > from mpl_toolkits.basemap import Basemap > > lon0, lat0, lon1, lat1 = (84.38, 26.22, 88.9, 29.8) > resolution = 'i' > > parallels = np.linspace(lat0, lat1, 5) > meridians = np.linspace(lon0, lon1, 5) > > f, ax = plt.subplots() > m = Basemap(lon0, lat0, lon1, lat1, resolution=resolution, ax=ax) > m.drawcountries(color=(1,1,0)) # country boundaries in pure yellow > m.drawrivers(color=(0,1,1)) # rivers in cyan > m.bluemarble() # NASA bluemarble image > m.drawmeridians(meridians, labels=[0,0,0,1], fmt='%.2f') > m.drawparallels(parallels, labels=[1,0,0,0], fmt='%.2f') > f.suptitle('The Himalayas'); > > ##### > > produces: > > http://img192.imageshack.us/img192/986/selection002e.png > > > This looks like a matplotlib bug, but I have no idea how easy it is to > fix. In the meantime, should we in ipython just revert back to not > using bbox_inches, or is there an alternative? > > Thanks! > > f > Not a bug. There are only so many artist objects we assume for determining the tight bbox. Suptitle is not one of them. However, If you collect all of the artists that you want considered, you can pass in a list of them to bbox_artists (IIRC) to have them considered as well. Now, with respect to the Basemap example, there might be a bug there, but it can still be worked around by passing in the list of labels to the kwarg. Cheers! Ben Root |
From: Jeff W. <js...@fa...> - 2012-01-29 16:32:58
|
On 1/29/12 8:42 AM, Benjamin Root wrote: > > > On Sunday, January 29, 2012, Fernando Perez <fpe...@gm... > <mailto:fpe...@gm...>> wrote: > > Hi all, > > > > in ipython for the qtconsole and notebook, we send inline figures using > > > > fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight') > > > > as seen here: > > > > > https://github.com/ipython/ipython/blob/master/IPython/core/pylabtools.py#L104 > > > > However, this produces truncated figure titles. Consider this code: > > > > f, ax = plt.subplots() > > ax.plot(rand(100)) > > ax.set_title('Axis title') > > f.suptitle('Figure title'); > > > > ### > > > > which produces this in the notebook: > > > > http://img546.imageshack.us/img546/5448/selection001c.png > > > > As you can see, the figure title gets truncated. > > > > We started using bbox_inches='tight' because otherwise in many cases > > the images were coming back with insane amounts of white padding, and > > Stefan vdW suggested this fix. But it seems that in other cases it > > actually loses data, which is even worse... > > > > A slightly more complicated example, using basemap, not only truncates > > the title but also all the x and y labels: > > > > from mpl_toolkits.basemap import Basemap > > > > lon0, lat0, lon1, lat1 = (84.38, 26.22, 88.9, 29.8) > > resolution = 'i' > > > > parallels = np.linspace(lat0, lat1, 5) > > meridians = np.linspace(lon0, lon1, 5) > > > > f, ax = plt.subplots() > > m = Basemap(lon0, lat0, lon1, lat1, resolution=resolution, ax=ax) > > m.drawcountries(color=(1,1,0)) # country boundaries in pure yellow > > m.drawrivers(color=(0,1,1)) # rivers in cyan > > m.bluemarble() # NASA bluemarble image > > m.drawmeridians(meridians, labels=[0,0,0,1], fmt='%.2f') > > m.drawparallels(parallels, labels=[1,0,0,0], fmt='%.2f') > > f.suptitle('The Himalayas'); > > > > ##### > > > > produces: > > > > http://img192.imageshack.us/img192/986/selection002e.png > > > > > > This looks like a matplotlib bug, but I have no idea how easy it is to > > fix. In the meantime, should we in ipython just revert back to not > > using bbox_inches, or is there an alternative? > > > > Thanks! > > > > f > > > > Not a bug. There are only so many artist objects we assume for > determining the tight bbox. Suptitle is not one of them. However, If > you collect all of the artists that you want considered, you can pass > in a list of them to bbox_artists (IIRC) to have them considered as well. > > Now, with respect to the Basemap example, there might be a bug there, > but it can still be worked around by passing in the list of labels to > the kwarg. > > Cheers! > Ben Root The lat and lon labels in Basemap are axes.text objects, which apparently are not considered when computing the bbox either. -Jeff |
From: Nathaniel S. <nj...@po...> - 2012-01-29 18:46:51
|
On Sun, Jan 29, 2012 at 7:42 AM, Benjamin Root <ben...@ou...> wrote: > Not a bug. There are only so many artist objects we assume for determining the tight bbox. Suptitle is not one of them. Why is this the desired behavior? -- Nathaniel |
From: Fernando P. <fpe...@gm...> - 2012-01-29 18:31:18
|
On Sun, Jan 29, 2012 at 10:22 AM, Nathaniel Smith <nj...@po...> wrote: >> Not a bug. There are only so many artist objects we assume for determining the tight bbox. Suptitle is not one of them. > > Why is this the desired behavior? I was just going to ask the same. And as Jeff Whitaker points out, all x and y (longitude/latitude) labels also get clipped. I can understand not considering the position of arbitrarily laid out text that a user could have put in a random location. But clipping something that is provided by a standard api call, such as a figure title, does seem much more like a bug than a feature to me, I'm afraid. Cheers, f |
From: Fernando P. <fpe...@gm...> - 2012-01-29 18:57:53
|
On Sun, Jan 29, 2012 at 10:30 AM, Fernando Perez <fpe...@gm...> wrote: > And as Jeff Whitaker points out, > all x and y (longitude/latitude) labels also get clipped. I meant to put at the end of that sentence: "in the basemap example". The simple plot has no clipping issues with labels, only with the suptitle. Cheers, f |
From: Benjamin R. <ben...@ou...> - 2012-01-29 19:25:46
|
On Sunday, January 29, 2012, Fernando Perez <fpe...@gm...> wrote: > On Sun, Jan 29, 2012 at 10:22 AM, Nathaniel Smith <nj...@po...> wrote: >>> Not a bug. There are only so many artist objects we assume for determining the tight bbox. Suptitle is not one of them. >> >> Why is this the desired behavior? > > I was just going to ask the same. And as Jeff Whitaker points out, > all x and y (longitude/latitude) labels also get clipped. > > I can understand not considering the position of arbitrarily laid out > text that a user could have put in a random location. But clipping > something that is provided by a standard api call, such as a figure > title, does seem much more like a bug than a feature to me, I'm afraid. > > Cheers, > > f > I certainly have no objections. Most likely it was an oversight. Ben Root |
From: Fernando P. <fpe...@gm...> - 2012-01-29 20:20:40
|
On Sun, Jan 29, 2012 at 11:25 AM, Benjamin Root <ben...@ou...> wrote: > I certainly have no objections. Most likely it was an oversight. OK, thanks. Filed so at least there's a record of it: https://github.com/matplotlib/matplotlib/issues/688 We'll find a workaround in ipython in the meantime. Cheers, f |
From: Jeff W. <js...@fa...> - 2012-01-29 20:26:37
|
On 1/29/12 11:30 AM, Fernando Perez wrote: > On Sun, Jan 29, 2012 at 10:22 AM, Nathaniel Smith<nj...@po...> wrote: >>> Not a bug. There are only so many artist objects we assume for determining the tight bbox. Suptitle is not one of them. >> Why is this the desired behavior? > I was just going to ask the same. And as Jeff Whitaker points out, > all x and y (longitude/latitude) labels also get clipped. > > I can understand not considering the position of arbitrarily laid out > text that a user could have put in a random location. From matplotlib's perspective, the lat/lon labels in Basemap are randomly located text objects - so it's not likely to ever work for Basemap plots unless matplotlib takes into account all the artist objects associated with a figure. -Jeff > But clipping > something that is provided by a standard api call, such as a figure > title, does seem much more like a bug than a feature to me, I'm afraid. > > Cheers, > > f |
From: Fernando P. <fpe...@gm...> - 2012-01-29 20:33:30
|
On Sun, Jan 29, 2012 at 12:26 PM, Jeff Whitaker <js...@fa...> wrote: > From matplotlib's perspective, the lat/lon labels in Basemap are > randomly located text objects - so it's not likely to ever work for > Basemap plots unless matplotlib takes into account all the artist > objects associated with a figure. Ah, OK. That's good to know, because then it means that the automatic use of 'tight' we make in ipython is probably over-aggressive then. I'll add your note above to the bug report, and we'll think how to best deal with it in ipython then. Cheers, f |
From: Jae-Joon L. <lee...@gm...> - 2012-01-30 04:03:23
|
On Mon, Jan 30, 2012 at 5:26 AM, Jeff Whitaker <js...@fa...> wrote: > unless matplotlib takes into account all the artist > objects associated with a figure. My primary reason behind not accounting all the artists was that, in general, Matplotlib does not know the exact bounding box of artists when the artists are clipped. In the current implementation, axes title, axis labels and ticklabels are only accounted, and we have an optional parameter of *bbox_extra_artists* so that users can manually change this behavior. By the way, for now, I'm more inclined to change the behavior to account all the texts artists (at least), although we may see white space sometimes. Regards, -JJ |
From: Jae-Joon L. <lee...@gm...> - 2012-01-30 04:49:50
|
Please see if this PR works. https://github.com/matplotlib/matplotlib/pull/689 Regards, -JJ On Mon, Jan 30, 2012 at 1:03 PM, Jae-Joon Lee <lee...@gm...> wrote: > On Mon, Jan 30, 2012 at 5:26 AM, Jeff Whitaker <js...@fa...> wrote: >> unless matplotlib takes into account all the artist >> objects associated with a figure. > > My primary reason behind not accounting all the artists was that, in > general, Matplotlib does not know the exact bounding box of artists > when the artists are clipped. > > In the current implementation, axes title, axis labels and ticklabels > are only accounted, and we have an optional parameter of > *bbox_extra_artists* so that users can manually change this behavior. > > By the way, for now, I'm more inclined to change the behavior to > account all the texts artists (at least), although we may see white > space sometimes. > > Regards, > > -JJ |