rafael-fuente / diffractsim

✨🔬 A flexible diffraction simulator for exploring and visualizing physical optics.
https://rafael-fuente.github.io/simulating-diffraction-patterns-with-the-angular-spectrum-method-and-python.html
Other
740 stars 91 forks source link

Plotting and Saving #50

Open MarnixMeersman opened 6 months ago

MarnixMeersman commented 6 months ago

Hi, I really like the existing plotting functions. The only thing is that I am looking for a way to export these "wavefront planes" as pure images without the matplotlib axes etc. So basically what you see hete below, but only what is contained inside the box. The thing is that a screenshot would not be sufficient as I would like to apply a certain manipulation to these raw outputs (which are not part of the library.) image

In an ideal world I would like there to be an option where I can export as image (jpeg,png etc) with a certain amount of pixels in x and y and the respective pixel size in microns. (Basically having the raw output of a simulated image sensor)

Would somebody know a workaround or existing function for this? It would be extremely helpful.

LtqxWYEG commented 3 weeks ago

I added a function to plot_colors.py in my fork.

def save_plot(self, rgb, figsize=(16, 16), xlim=None, ylim=None, text=None, path="pic.png", dark_background=True, tight=True):
    from ..util.backend_functions import backend as bd
    if bd != np:
        rgb = rgb.get()

    if dark_background:
        plt.style.use("dark_background")
    else:
        plt.style.use("default")

    fig = plt.figure(figsize = figsize)
    ax = fig.add_subplot(1, 1, 1)

    if xlim is not None:
        ax.set_xlim(np.array(xlim) / mm)

    if ylim is not None:
        ax.set_ylim(np.array(ylim) / mm)

    ax.set_xlabel("[mm]")
    ax.set_ylabel("[mm]")

    if text is None:
        ax.set_title("Screen distance = " + str(self.z * 100) + " cm")
    else:
        ax.set_title(text)

    im = ax.imshow(
        rgb,
        extent = [
            float(self.x[0] - self.dx / 2) / mm,
            float(self.x[-1] + self.dx / 2) / mm,
            float(self.y[0] - self.dy / 2) / mm,
            float(self.y[-1] + self.dy / 2) / mm,
        ],
        interpolation = "spline36", origin = "lower"
    )
    if tight:
        fig.savefig(path, bbox_inches = 'tight')
    else:
        fig.savefig(path)  # save the figure to file
    plt.close(fig)  # close the figure window

You could remove ax.set_xlabel and ax.set_title and try it out. If you change figsize you can change the resulting image size.
If you use my fork, you simply call it like that: F.save_plot(rgb, figsize = (16, 16), path = imagefile, tight = True) It needed some changes to _init_.py and mono-/polychromatic-simulator.py so it works just like F.plot_colors.