Different figsize definition in Matplotlib 2.0 - python

I have recently updated matplotlib from 1.5 to 2.0
I have noticed a difference in the definition of figsize parameter in plt.subplots:
In matplotlib 1.5, figsize would set the dimension of the window generated
In matplotlib 2.0, figsize would set the dimension of the plot only
So to make an example, I used to set figsize = (23, 8) that would generate a window that almost perfectly fitted the width of my screen.
Now the same parameters generate a window that exceeds the width of the screen, but if I center the window I see that the actual plot fits the window of the screen.
Is there a way to revert to previous convention, where I specify the size of the window?

In case somebody had the same problem, I have found the solution looking at the matplotlib 2.0 documentation.
The change is due to a change in the default screen dpi from 80 to 100, as documented here. This had the effect (among others) of making the figure size appear bigger on the screen. (In order to mitigate this, in fact, the default figure size was reduced from 8x6 inches to 6.4x4.8 inches).
So in order to restore the same window size in matplotlib 2.0, I re-set the figure dpi to 80:
import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 80

Related

How to increase matplotlib figure dpi without increasing the window size of the shown plot?

I want to increase the dpi of plots in matplotlib, but the window that displays the plot gets far too large when deviating from the default of
100. I've been using
import matplotlib
matplotlib.rcParams['figure.dpi'] = 300
matplotlib.rcParams['figure.figsize'] = (6.4, 4.8)
to increase the dpi of all plots shown and forcing it to have the default size but it still has the size issue. I would like it so that all plots displayed are uniform in size and dpi without having to individually set this for every figure. Any way to do this?
I think that this won't work as you wish for. The resolution (given in dpi) determines how many points an inch has. The size defines how many inches the figure should have. But none of both sets the number of pixels that your monitor should display for an inch. The thing is that matplotlib and python do not resize plots (only images). So if you save the plot as an image and open it again (with any image viewer) and you click on "show me 100% size", the figure will behave as you intended it to. But while drawing the pixels in a plot (that is what matplotlib does if you call matplotlib.pyplot.draw()), it needs to draw every pixel, which is why one might think that figuresize and dpi both result in a larger plot in matplotlib. Essentially figuresize tells the image viewer how to resize the image when displaying it.
I found this post is particularly useful for explaining the different behavior of size and resolution.

How can I scale inline matplotlib figures within JupyterLab?

I'm trying out JupyterLab having used Jupyter notebooks for some time. I use the standard %matplotlib inline magic at the start. I've noticed that JupyterLab displays matplotlib figures much larger than Jupyter notebooks used to.
Is there a way to force JupyterLab to display the images in smaller window/area? I know I can change the figsize I pass when creating the figure but that does not scale the text/labels within the figure and I end up with effectively oversize labels and titles.
Ideally within JupyterLab I'd like to be able to set it up so images fit in an area I can define the size of and if they're larger they get scaled to fit.
I've been reading the JupyterLab docs but nothing leaps out at me at solving this particular problem.
Update: I'm running JupyterLab in Chrome. Chrome displays images up to the full width of the browser window; if the window is smaller than that width that allows the full size of the image, the image is scaled to fit - this is fully dynamic, if you shrink the width of the window the image will rescale on the fly. I changed my figsize parameter (and carefully adjusted font sizes to work) and I got a reasonably sized figure in JuptyerLab. I noticed that when I saved this to a jpg and put that in a powerpoint doc is was quite small (3,2). So I enlarged it, but it became blurred. So I regenerated it with dip=1200. The figure in JuputerLab got bigger. So JupyterLab does not respect the figsize. It's making somekind of judgement based on the number of pixels in the image.
Update 2: This piece of code demonstrates that the Juptyer Lab front end doesn't display images according to the figsize parameter but the product of figsize and dpi (upto the width of the screen, after which it is scaled to fit, presumably by Chrome itself). Note that the font size you see on the screen scales only with dpi and not with figsize (as it should).
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
xys = np.random.multivariate_normal([0.0, 0.0], [[1.0,-0.5],[-0.5,1.0]], 50)
for figsize in [(3,2),(6,4)]:
for dpi in [25,50,100]:
fig = plt.figure(figsize=figsize, dpi=dpi)
ax = fig.add_subplot(1,1,1)
ax.scatter(xys[:,0], xys[:,1])
ax.set_title('figsize = {}, dip = {}'.format(figsize, dpi))
A work around is to work in Jupyter Lab generating figures at a low dpi setting but saving figures at a high dpi setting for publications.

How to increase the physical size of axes in matplotlib pyplot?

I am plotting the following graph,
I would like to change the physical size of the axes. I have plotted the xticks in hopes of being able to increase the spacing between them and thus increase the physical size of the axes, but no luck. I want a resulting image, that is possibly very large, but when zoomed in, I am able to see individual points and the arrows plotted. I tried changing the size of the figure, but it just creates a larger image, with higher resolution, and same level of detail as before, it does not allow me to see more points when I zoom in.
Can someone please tell me how can I increase the physical size of the axes so when I zoom in on the saved image (right now I'm saving it in a pdf format) I can see individual points? Thanks so much
You could try plt.figure(figsize=(20, 10)) in order to increase the width of the figure. It should be possible to obtain a suitable ratio of height and width by playing with these numbers (20=width, 10=height). There is a similar question here: How do you change the size of figures drawn with matplotlib?

Fine control over the font size in Seaborn plots

I'm currently trying to use Seaborn to create plots for my academic papers. The plots look great and easy to generate, but one problem that I'm having some trouble with is having the fine control on the font size in the plots.
My font size in my paper is 9pt and I would like to make sure the font size in my plots are either 9pt or 10pt. But in seaborn, the font size is mainly controlled through font scale sns.set_context("paper", font_scale=0.9). So it's hard for me to find the right font size except through trial and error. Is there a more efficient way to do this?
I also want to make sure the font size is consistent between different seaborn plots. But not all my seaborn plots have the same dimension, so it seems like using the same font_scale on all the plots does not necessarily create the same font size across these different plots?
I've attached my code below. I appreciate any comments on how to format the plot for a two column academic paper. My goal is to be able to control the size of the figure without distorting the font size or the plot. I use Latex to write my paper.
# Seaborn setting
sns.set(style='whitegrid', rc={"grid.linewidth": 0.1})
sns.set_context("paper", font_scale=0.9)
plt.figure(figsize=(3.1, 3)) # Two column paper. Each column is about 3.15 inch wide.
color = sns.color_palette("Set2", 6)
# Create a box plot for my data
splot = sns.boxplot(data=df, palette=color, whis=np.inf,
width=0.5, linewidth = 0.7)
# Labels and clean up on the plot
splot.set_ylabel('Normalized WS')
plt.xticks(rotation=90)
plt.tight_layout()
splot.yaxis.grid(True, clip_on=False)
sns.despine(left=True, bottom=True)
plt.savefig('test.pdf', bbox_inches='tight')
You are right. This is a badly documented issue. But you can change the font size parameter (by opposition to font scale) directly after building the plot. Check the following example:
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
b = sns.boxplot(x=tips["total_bill"])
b.axes.set_title("Title",fontsize=50)
b.set_xlabel("X Label",fontsize=30)
b.set_ylabel("Y Label",fontsize=20)
b.tick_params(labelsize=5)
plt.show()
, which results in this:
To make it consistent in between plots I think you just need to make sure the DPI is the same. By the way it' also a possibility to customize a bit the rc dictionaries since "font.size" parameter exists but I'm not too sure how to do that.
NOTE: And also I don't really understand why they changed the name of the font size variables for axis labels and ticks. Seems a bit un-intuitive.
It is all but satisfying, isn't it? The easiest way I have found to specify when setting the context, e.g.:
sns.set_context("paper", rc={"font.size":8,"axes.titlesize":8,"axes.labelsize":5})
This should take care of 90% of standard plotting usage. If you want ticklabels smaller than axes labels, set the 'axes.labelsize' to the smaller (ticklabel) value and specify axis labels (or other custom elements) manually, e.g.:
axs.set_ylabel('mylabel',size=6)
you could define it as a function and load it in your scripts so you don't have to remember your standard numbers, or call it every time.
def set_pubfig:
sns.set_context("paper", rc={"font.size":8,"axes.titlesize":8,"axes.labelsize":5})
Of course you can use configuration files, but I guess the whole idea is to have a simple, straightforward method, which is why the above works well.
Note: If you specify these numbers, specifying font_scale in sns.set_context is ignored for all specified font elements, even if you set it.
I've just spent way too long trying to find out the actual values of the "paper" sns context. I could only find it for "talk" and honestly I am raging! Just going to use
sns.set_context("paper", rc{"font.size":8,"axes.titlesize":8,"axes.labelsize":5})
even though these might be the values anyway!!!!

How can I keep figure size constant with matplotlib although using pyplot.show()?

Look at the following python example:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['figure.figsize'] = [8.27, 11.69]
fig = plt.figure()
plt.show() # This line causes problems with figsize
fig.savefig('test.pdf')
If I use "plt.show()" the figure size of test.pdf changes a lot (from
210 x 297 [mm] to
213 x 250 [mm]
What do I have to do in order to keep it constant?
There's a good demo on adjusting image size in matplotlib figures on the SciPy site.
The effect of show() on the figure size will depend upon which matplotlib backend is used. For example, when I used the TkAgg backend (the default on my system) it added about 12 pixels to the width and height of the figure. But when I switched to the WXAgg backend, the figure size was actually reduced.
In addition, manually resizing the window displayed by show() will also change the figure size. Moreover, if displaying the figure would require a window too large for the screen, then the window size will be reduced, and the figure size reduced accordingly.
In any case, your best bet is likely going to be to reset the figure size before rendering the pdf. I.e.:
fig.set_size_inches(8.27, 11.69)
fig.savefig('test.pdf')

Categories