1

I'm trying to get a plot with custom aspect ratio to display properly. I am using Jupyter notebooks for the rendering, but the way I've normally done this is to adjust the 'figsize' attribute in the subplots. I've done it like below:

from matplotlib import pyplot as plt
fig,axes = plt.subplots(1,1,figsize=(16.0,8.0),frameon=False)

The problem is that, while the aspect ratio seems to come out correct (judging by eye), the figure does not use up even close to the whole page width, and is therefore tiny and hard to read.

I guess it's behaving like there are some sort of margins set on the left and right, but I can't find the global setting that controls this. I have been using the list of settings here, with no success finding a relevant one.

My question(s) are

  1. How do I adjust the aspect ratio without impacting the overall size of the figure (think font sizes of the axis labels)? I don't need the width of my screen to be a constraint, I'd be perfectly happy for Jupyter notebooks to give me a horizontal scroll bar.
  2. Is there a place with a more comprehensive and well-written documentation of all the matplotlib parameters that are available? The one I linked above is awkward because it gives the parameters in the form of an example matplotlibrc file. I'd like to know if a single page with (good) descriptions of all the parameters exists.

EDIT: it has been pointed out that this could be a jupyter problem and that I am setting the aspect ratio correctly. I'm using Jupyter version 1.0.0. Below is a picture of the output of a simplified notebook.

picture of figure from ipy notebook

It's easy to see that the figure does not use even close to the available horizontal space.

The code in the notebook is:

#imports
import numpy as np

#set up a plot 
import matplotlib as mpl
from matplotlib import pyplot as plt
#got smarter about the mpl config: see mplstyles/ directory
plt.style.use('standard')

#set up a 2-d plot

fig,axes = plt.subplots(1,1,figsize=(16.0,8.0),frameon=False)
ax1 = axes

#need to play with axis
mpl.rcParams['ytick.minor.visible'] = False

xmin = -10
xmax = 10
ymin = -10 
ymax = 10
x = np.random.normal(0,5,(20000,))
y = np.random.normal(0,5,(20000,))
h = ax1.hist2d(x,y, bins=200, cmap='inferno')
ax1.set_xlim(xmin,xmax)
ax1.set_ylim(ymin,ymax)
ax1.set_xlabel('epoch time [Unix]',**axis_font) 
ax1.set_ylabel(r'relative time [$\mu$s]',**axis_font)
ax1.grid(True)


#lgnd= ax1.legend(loc=2,prop={'size':22})

for axis in ['top','bottom','left','right']:
  ax1.spines[axis].set_linewidth(2)

plt.tight_layout()
#plt.savefig('figures/thefigure.eps')
plt.show()

The mpl style file that I use in the plt.style.use command is:

#trying to customize here, see:
#https://matplotlib.org/users/customizing.html
#matplotlib.rc('figure', figsize=(3.4, 3.4*(4/6)))
lines.linewidth : 2

#ticks
xtick.top : False
xtick.bottom : True
xtick.minor.visible : True
xtick.direction : in
xtick.major.size : 8
xtick.minor.size : 4
xtick.major.width : 2
xtick.minor.width : 1
xtick.labelsize : 22

ytick.left : True
ytick.right : False
ytick.minor.visible : True
ytick.direction : in
ytick.major.size : 8
ytick.minor.size : 4
ytick.major.width : 2
ytick.minor.width : 1
ytick.labelsize : 22


#error bars
#errorbar.capsize : 3

#axis stuff
axes.labelsize : 22

EDIT 2: restricting the range of the vectors to the range of the axes before plotting results in the desired output. See the below figure:

modified jupyter notebook

The added/modified lines were:

xnew = x[(np.abs(x)<10) & (np.abs(y)<10)]
ynew = y[(np.abs(x)<10) & (np.abs(y)<10)]
h = ax1.hist2d(xnew,ynew, bins=200, cmap='inferno')
6
  • The matplotlib documentation is pretty comprehensive. The matplotlibrc file does not contain the complete API, only the paramters which can be set via the style file. Setting the figure size in matplotlib is pretty straight forward (you're doing it correctly). Any problems you may encounter could also result from jupyter, not matplotlib (hence the matplotlib documentation cannot cover them). Commented May 7, 2018 at 16:53
  • @ImportanceOfBeingErnest I agree that the matplotlib documentation is pretty comprehensive. If you have a comment about this question, could you please point me directly to a page that documents all of the set-able parameters or confirm that the page I linked does. Commented May 7, 2018 at 17:15
  • As said, the matplotlibrc file contains all the properties that can be set as rc parameters. Those are of course not all properties that can be set via the API in general (as matplotlib is object oriented). From version 2.2 on, it is ensured that the matplotlib rc file that appears in the documentation contains all settable parameters. Commented May 7, 2018 at 17:40
  • @ImportanceOfBeingErnest then, is there a link to a comprehensive list of all of the parameters that affect the rendering of figures, or are you saying that each object has its parameters documented separately? If so, I would appreciate you pointing me to one, say the axis object? Commented May 7, 2018 at 17:51
  • 1
    Here is the compelte API, divided by submodules. In particular, the axes and the axis. Concerning your problem, I think there is a bug involved. I will investigate a bit further and see if there is a workaround. Commented May 7, 2018 at 18:39

2 Answers 2

1

Apparently there was a bug in matplotlib 2.2.2 which got fixed by now in the development version. You may of course install the current development version from github.

The Problem comes from setting axes limits (ax1.set_xlim(-10,10)) which are smaller than the initial image. For some reason the original limits still got used to calculate the tight bbox for saving as png.

The workaround would be not to set any axes limits manually, but let the histogram plot be calculated directly with the desired limits in mind. In this case -10,10, e.g.:

x = np.random.normal(0,5,(20000,))
y = np.random.normal(0,5,(20000,))
bins = np.linspace(-10,10,201)
h = ax1.hist2d(x,y, bins=bins, cmap='inferno')
Sign up to request clarification or add additional context in comments.

1 Comment

Or, apparently, you can restrict the data to be consistent with the images before plotting, as I did in the post in EDIT 2.
0

To change the font sizes of the axis label's, you'd have to use plt.rc or plt.rcParams (more on this here), so you needn't worry about doing that when using figsize.

I don't see any problems with the code you posted, could you post a picture of what you get and what you'd like to get? This is what I get using that configuration, on Jupyter notebooks, just plotting a very simple graph: Plot on Jupyter notebook

Do note, however, Jupyter limits the size of your plots automatically (see below): Plot with max width Plot with no max width

And I'm afraid I can't help you with your second question, as I've always found matplotlib's documentation sufficient for all my needs... good luck!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.