def compare_results(image, image_ngmix, image_me):

    # to facilitate comparison:
    vmin = np.min([image, image_ngmix, image_me])
    vmax = np.max([image, image_ngmix, image_me])
    fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(8 * 3, 6 * 2), sharex=False, sharey=False, squeeze=False)

    # input
    ax = axs[0, 0]
    ax.set_xlim(0, image.shape[0])
    ax.set_ylim(0, image.shape[1])
    ax.set_title("input")
    IM = ax.imshow(image, cmap=reds, vmin=vmin, vmax=vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)

    # output
    ax = axs[0, 1]
    ax.set_xlim(0, image.shape[0])
    ax.set_ylim(0, image.shape[1])
    ax.set_title("ngmix")
    IM = ax.imshow(image_ngmix, cmap=reds, vmin=vmin, vmax=vmax)
    CB = fig.colorbar(IM, ax=ax)

    ax = axs[0, 2]
    ax.set_xlim(0, image.shape[0])
    ax.set_ylim(0, image.shape[1])
    ax.set_title("me")
    IM = ax.imshow(image_me, cmap=reds, vmin=vmin, vmax=vmax)
    CB = fig.colorbar(IM, ax=ax)

    ax = axs[1, 0]
    ax.set_axis_off()

    # residual
    image_ngmix = image_ngmix / image.max()
    image_me = image_me / image.max()
    image = image / image.max()
    diff_ngmix = (image - image_ngmix) * 100
    diff_me = (image - image_me) * 100
    vmax = np.max([diff_ngmix, diff_me])
    vmin = np.min([diff_ngmix, diff_me])
    cmap = shiftedColorMap_minmax(blue_red, vmin=vmin, vmax=vmax, name="shifted")

    ax = axs[1, 1]
    ax.set_xlim(0, image.shape[0])
    ax.set_ylim(0, image.shape[1])
    IM = ax.imshow(diff_ngmix, cmap=cmap, vmin=vmin, vmax=vmax)
    CB = fig.colorbar(IM, ax=ax)
    ax.set_title("ngmix residual (percent)")

    ax = axs[1, 2]
    ax.set_xlim(0, image.shape[0])
    ax.set_ylim(0, image.shape[1])
    IM = ax.imshow(diff_me, cmap=cmap, vmin=vmin, vmax=vmax)
    CB = fig.colorbar(IM, ax=ax)
    ax.set_title("me residual (percent)")
    fig.tight_layout()

    return fig, axs
def show_results(psf_image, gal_image, conv_image,
                 psf_fit_image, gal_fit_image, conv_fit_image):

    # psf | gal | conv
    # psf_fit | gal_fit | conv_fit
    # psf_res | gal_res | conv_res
    
    # residuals
    psf_res_image = (psf_image - psf_fit_image)
    psf_res_vmin = -np.max(np.abs(psf_res_image))
    psf_res_vmax = np.max(np.abs(psf_res_image))
    psf_res_cmap = shiftedColorMap_minmax(blue_red,
                                          #vmin=psf_res_image.min(),
                                          vmin=psf_res_vmin,
                                          vmax=psf_res_vmax,
                                          name='psf_res_shifted')
    
    gal_res_image = (gal_image - gal_fit_image)
    gal_res_vmin = -np.max(np.abs(gal_res_image))
    gal_res_vmax = np.max(np.abs(gal_res_image))
    gal_res_cmap = shiftedColorMap_minmax(blue_red,
                                          #vmin=gal_res_image.min(),
                                          vmin=gal_res_vmin,
                                          vmax=gal_res_vmax,
                                          name='gal_res_shifted')

    conv_res_image = (conv_image - conv_fit_image)
    conv_res_vmin = -np.max(np.abs(conv_res_image))
    conv_res_vmax = np.max(np.abs(conv_res_image))
    conv_res_cmap = shiftedColorMap_minmax(blue_red,
                                          #vmin=conv_res_image.min(),
                                          vmin=conv_res_vmin,
                                          vmax=conv_res_vmax,
                                          name='conv_res_shifted')

    
    # figure
    
    ncols = 3
    nrows = 3
    fig, axs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(5 * ncols, 4 * nrows),
                            sharex=False, sharey=False, squeeze=False)

    # vmins and vmaxs
    psf_vmin = np.min([psf_image, psf_fit_image])
    psf_vmax = np.max([psf_image, psf_fit_image])
    gal_vmin = np.min([gal_image, gal_fit_image])
    gal_vmax = np.max([gal_image, gal_fit_image])
    conv_vmin = np.min([conv_image, conv_fit_image])
    conv_vmax = np.max([conv_image, conv_fit_image])

    # input
    ax = axs[0, 0]
    ax.set_xlim(0, psf_image.shape[0])
    ax.set_ylim(0, psf_image.shape[1])
    ax.set_title('psf')
    IM = ax.imshow(psf_image, cmap=reds, vmin=psf_vmin, vmax=psf_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)

    ax = axs[0, 1]
    ax.set_xlim(0, gal_image.shape[0])
    ax.set_ylim(0, gal_image.shape[1])
    ax.set_title('gal')
    IM = ax.imshow(gal_image, cmap=reds, vmin=gal_vmin, vmax=gal_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)
    
    ax = axs[0, 2]
    ax.set_xlim(0, conv_image.shape[0])
    ax.set_ylim(0, conv_image.shape[1])
    ax.set_title('convolved')
    IM = ax.imshow(conv_image, cmap=reds, vmin=conv_vmin, vmax=conv_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)
    
    # fits
    ax = axs[1, 0]
    ax.set_xlim(0, psf_fit_image.shape[0])
    ax.set_ylim(0, psf_fit_image.shape[1])
    ax.set_title('psf fit')
    IM = ax.imshow(psf_fit_image, cmap=reds, vmin=psf_vmin, vmax=psf_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)

    ax = axs[1, 1]
    ax.set_xlim(0, gal_fit_image.shape[0])
    ax.set_ylim(0, gal_fit_image.shape[1])
    ax.set_title('gal fit')
    IM = ax.imshow(gal_fit_image, cmap=reds, vmin=gal_vmin, vmax=gal_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)
    
    ax = axs[1, 2]
    ax.set_xlim(0, conv_fit_image.shape[0])
    ax.set_ylim(0, conv_fit_image.shape[1])
    ax.set_title('convolved fit')
    IM = ax.imshow(conv_fit_image, cmap=reds, vmin=conv_vmin, vmax=conv_vmax)  # different cbar!
    CB = fig.colorbar(IM, ax=ax)
    
    # residuals
    
    ax = axs[2, 0]
    ax.set_xlim(0, psf_res_image.shape[0])
    ax.set_ylim(0, psf_res_image.shape[1])
    IM = ax.imshow(psf_res_image, cmap=psf_res_cmap,
                   vmin=psf_res_vmin,
                   vmax=psf_res_vmax)
    ax.set_title('psf residual')
    CB = fig.colorbar(IM, ax=ax)

    ax = axs[2, 1]
    ax.set_xlim(0, gal_res_image.shape[0])
    ax.set_ylim(0, gal_res_image.shape[1])
    IM = ax.imshow(gal_res_image, cmap=gal_res_cmap,
                   vmin=gal_res_vmin,
                   vmax=gal_res_vmax)
    ax.set_title('gal residual')
    CB = fig.colorbar(IM, ax=ax)
    
    ax = axs[2, 2]
    ax.set_xlim(0, conv_res_image.shape[0])
    ax.set_ylim(0, conv_res_image.shape[1])
    IM = ax.imshow(conv_res_image, cmap=conv_res_cmap,
                   vmin=conv_res_vmin,
                   vmax=conv_res_vmax)
    ax.set_title('conv residual')
    CB = fig.colorbar(IM, ax=ax)
    
    
    
    fig.tight_layout()
    
    return fig, axs
# components
ax = axs[1, 0]
ax.set_axis_off()

ax = axs[1, 1]
ax.set_xlim(0, image.shape[0])
ax.set_ylim(0, image.shape[1])
ax.set_title("2 fit")
IM = ax.imshow(image_2_fit, cmap=reds, vmin=vmin, vmax=vmax)
CB = fig.colorbar(IM, ax=ax)

# residual
diff_12 = image_12 - image_12_fit
vmin_12_resid = diff_12.min()
vmax_12_resid = diff_12.max()
cmap_12_resid = shiftedColorMap_minmax(blue_red, vmin=vmin_12_resid, vmax=vmax_12_resid)

ax = axs[2, 2]
ax.set_xlim(0, image.shape[0])
ax.set_ylim(0, image.shape[1])
IM = ax.imshow(diff_12, cmap=cmap_12_resid, vmin=vmin_12_resid, vmax=vmax_12_resid)  # different cbar!
CB = fig.colorbar(IM, ax=ax)

ax = axs[2, 0]
ax.set_axis_off()

diff_2 = image_2 - image_2_fit
vmin_2_resid = diff_2.min()
vmax_2_resid = diff_2.max()
cmap_2_resid = shiftedColorMap_minmax(blue_red, vmin=vmin_2_resid, vmax=vmax_2_resid)
ax = axs[2, 1]