Open kolibril13 opened 3 years ago
Hi @kolibril13!
I won't say it's not possible, but I've never seen a way to do it. I say this as a daily user of Matplotlib. savefig()
is ment to store the figure with labels, annotations, scalebars (!), and much much more (documentation), while imsave()
cannot store any of those things (documentation).
Could I ask why you would want this? I assume the scalebar would look quite pixelated?
hello @hakonanes !
Thanks for your explanation.
What I am looking for is to use savefig()
with my image and ScaleBar then.
The reason I want to do this: I want to show images with a scalebar on a poster.
As these images have a resolution about 2000x2000 pixel, I don't want to lose image quality when adding the scalebar.
As I am making the poster with a vector program, I can simply save the image as a pdf.
The image is then a raster image, and the Scalebar is still in vector format.
As these images have a resolution about 2000x2000 pixel, I don't want to lose image quality when adding the scalebar.
Aha, the scalebar would not be pixelated, then, wrong assumption on my end...
As I am making the poster with a vector program, I can simply save the image as a pdf. The image is then a raster image, and the Scalebar is still in vector format.
I would increase the dots per inch (DPI), as you do, to ensure that you don't loose much pixel resolution. Apart from that, I don't know what else can help, unfortunately. It might be that just adding a custom scalebar in your program yourself is the simplest solution when you want to keep the exact image resolution.
Here is a solution I found:
import matplotlib.pyplot as plt
import numpy as np
def export_figure_matplotlib(arr, f_name, dpi=200, resize_fact=1, plt_show=False): """ Export array as figure in original resolution :param arr: array of image to save in original resolution :param f_name: name of file where to save figure :param resize_fact: resize facter wrt shape of arr, in (0, np.infty) :param dpi: dpi of your screen :param plt_show: show plot or not """ fig = plt.figure(frameon=False) fig.set_size_inches(arr.shape[1]/dpi, arr.shape[0]/dpi) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(arr) scalebar = ScaleBar(650, "nm", length_fraction=0.25, location= "lower right") ax.add_artist(scalebar) plt.savefig(f_name, dpi=(dpi * resize_fact)) if plt_show: plt.show() else: plt.close()
export_figure_matplotlib(my_slice3, "hello2.pdf", dpi=298, resize_fact=1, plt_show=True)
Inspired by https://stackoverflow.com/a/51438809/6933377
Thank you for sharing the code. I would propose to add this snippet to the README. Can I clarify two things?
fig.set_size_inches
instead of passing the size to plt.figure? dpi
can also be passed in there instead of when calling savefig
plt.figure(figsize=(image_width / dpi, image_height / dpi), frameon=False, dpi=dpi)
ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])
So I would go with this snippet if @kolibril13 agrees:
fig = plt.figure(figsize=(arr.shape[1] / dpi, arr.shape[0] / dpi), frameon=False, dpi=dpi)
ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])
ax.set_axis_off()
ax.imshow(arr)
scalebar = ScaleBar(650, "nm", length_fraction=0.25, location= "lower right")
ax.add_artist(scalebar)
Hi! I want to save my plot with the ScaleBar, here is my code:
When I save the image, the resolution is not anymore the resolution of the original image. At Stack Overflow I found the hint, that one can use
imsave
, but that is not working with the Scalebar. https://stackoverflow.com/questions/31544130/saving-an-imshow-like-image-while-preserving-resolution I know that I can increase the resolution e.g. withplt.rcParams['figure.dpi'] = 300
. But that is not leading to the exact pixel-by-pixel image. Any idea how to solve this?