Increase dpi in matplotlib chart without changing it's size - python

I'm trying to create a pdf using Python's reportlab module.
I generated a png with matplotlib and saved it in the pdf file using report labs canvas.drawImage method.
My problem is that the generated png file is very fuzzy. I specified the size in inches with plt.figure(figsize=(20,10)) and saved the picture with the plt.savefig method.
This works out perfectly (except the fuzzy quality of the picture).
But when I increase the dpi within the savefig method the size of the picture increases.
Is there any way to improve the dpi without changing the picture size.
Or is there a way to resize it to the predefined values?
Thanks!

f = df.plot()
fig = f.get_figure()
fig.set_size_inches((2,2))
fig.savefig('C:/temp/foo.png', bbox_inches='tight', dpi=1500)

Related

Matplotlib colourmap creating different images when using method .imsave() and .savefig()

I've been working on temperature maps and have been trying to save images using the matplotlib colourmap viridis. Originally, I was using the following code to create images and then save them:
# define normalisation and colourmap
norm = Normalize(vmin=2, vmax=42)
cmap = plt.get_cmap('viridis').copy()
cmap.set_bad('white', 1.)
# apply colourmap to normalised data
map = cmap(norm(map))
# create and save figure
plt.imshow(map, cmap=cmap)
plt.axis('off')
plt.savefig(imgpath, bbox_inches='tight', pad_inches=0)
plt.cla()
This method was giving me the following image:
result using plt.imshow() and plt.savefig()
I quickly noticed that plt.savefig() does not save the image with the original pixel resolution, but does so based on my screen resolution. So instead, I used plt.imsave, which preserves the original size of the array. Because plt.imsave doesn't have a flag for cmap, I applied it directly as follows:
plt.imsave(imgpath, arr=cmap(norm(map)), format='png')
However, using plt.imsave gave me a different map: result using plt.imsave(). The same thing happens when cmap is applied directly when using plt.imshow()
I can't figure out what I'm doing wrong, I've tried with different maps from different areas, I'm sure that I've been using exactly the same instance of the colourmap and normalisation on both methods.
Can anyone tell me what the difference between the two methods is?

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 improve the quality of my plots in matplotlib?

When I save my plots with plt.savefig() in PNG format the figures generated are very bad resolution. I've tried to save in PDF format and define a high number of dpi, but when I use images in that format in LaTeX, my file becomes very heavy and the PDF generated takes to much time to render.
How can I generate images with better quality and do not make my pdf generated by LaTeX so dificult to render?
:

Saving images from plotly

How can I save images generated with plotly in different formats? Only "Download as PNG" is possible from the generated HTML figure. I would need to interact with the figure (change rotation, choose which data to plot) and save an .eps figure for each online modified plot. Thanks a lot!
Plotly supports exporting to EPS (the docs mention that you need the poppler library) and the Figure object has a write_image method that saves a figure to a file.
You can specify the format through the filename and the resolution with the width and height keyword arguments, representing logical pixels.
You can read more on static image exporting in Plotly here. This is a code example:
fig.write_image("name.eps", width=1920, height=1080)
In order to select what is plotted you will have to set the figure's camera controls.

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.

Categories