Commit 7a79dc7d authored by Vacaliuc, Bogdan's avatar Vacaliuc, Bogdan
Browse files

slides/4: drop "NOT shown / RoundUpPixel is separate" panel; add zoom inset



Right-hand panel of slide 4 had two explanatory sub-paragraphs
("Note — what is NOT shown" and "RoundUpPixel is separate") that
were inherited from the synthetic-data version.  Scientists flagged
them as redundant now that the slide shows real data; removed.

Added a matplotlib inset_axes zoom on the upper-right showing the
low-S/N region where the autoreduce curve drops below the GUI curve
(the ErrorWeightedBackground over-subtraction callout).  Connected
with a dashed mark_inset rectangle so the viewer sees which Q range
is being magnified.  Legend moved to lower-right to stay clear of
the inset and the zoom-origin rectangle.

Co-Authored-By: default avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
parent 72cdba18
Loading
Loading
Loading
Loading
+49 −25
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ def main():
    pax.set_ylabel(r"Reflectivity $R(Q_z)$", fontsize=17, family=FAMILY, labelpad=8)
    pax.grid(True, which="both", alpha=0.22)
    pax.tick_params(labelsize=13)
    leg = pax.legend(loc="lower left", fontsize=13.5, frameon=True,
    leg = pax.legend(loc="lower right", fontsize=13, frameon=True,
                     framealpha=0.97, edgecolor="#BBBBBB")
    leg.get_frame().set_boxstyle("round,pad=0.3")

@@ -167,10 +167,10 @@ def main():
            # guaranteed not to overflow the plot area.
            pax.annotate(
                "at low S/N the autoreduce\nbackground estimator\n"
                "over-subtracts here\n(ErrorWeightedBackground=True)",
                "over-subtracts\n(ErrorWeightedBackground=True)",
                xy=(q_auto[i_auto], r_auto[i_auto]),
                xycoords="data",
                xytext=(0.30, 0.08),
                xytext=(0.03, 0.06),
                textcoords="axes fraction",
                fontsize=12, color="#8C3A00", family=FAMILY, fontweight="bold",
                arrowprops=dict(arrowstyle="->", color="#8C3A00", lw=1.3),
@@ -225,29 +225,53 @@ def main():
        "the estimate when off-specular intensity leaks into the\n"
        "background band — R(Q) silently pushed down at low S/N.")

    # Note about the third callout
    info.text(0.03, 0.33, "Note — what is NOT shown",
              fontsize=15, fontweight="bold", color="#606060",
              ha="left", va="top", family=FAMILY)
    info.text(0.03, 0.29,
              "The earlier deck showed a 'post-hoc scaling' callout.\n"
              "That claim was incorrect — it does not cause the\n"
              "disagreement.  Dropped for this slide.",
              fontsize=11.5, color="#444", ha="left", va="top",
              family=FAMILY, style="italic")

    info.text(0.03, 0.18, "RoundUpPixel is separate",
              fontsize=15, fontweight="bold", color="#606060",
              ha="left", va="top", family=FAMILY)
    info.text(0.03, 0.14,
              "It only matters when ConstantQBinning=True; the\n"
              "fixture runs do not exercise that path.  If the hack-\n"
              "a-thon wants a demo, pick a run reduced with const-Q.",
              fontsize=11.5, color="#444", ha="left", va="top",
              family=FAMILY, style="italic")

    # summary box
    # ── Zoom inset on the background-over-subtraction callout ──────────
    # Show the low-S/N region where the autoreduce curve drops below the GUI
    # curve. Zoom in tight on the high-Q end of the common Q range.
    from mpl_toolkits.axes_grid1.inset_locator import mark_inset
    from matplotlib.patches import Rectangle

    if len(common) > 10:
        # Pick the highest-Q third of the common range
        q_cut_lo = float(common[int(0.55 * len(common))])
        q_cut_hi = float(common[-1])
        sub_mask_gui = (q_gui >= q_cut_lo) & (q_gui <= q_cut_hi) & (r_gui > 0)
        sub_mask_auto = (q_auto >= q_cut_lo) & (q_auto <= q_cut_hi) & (r_auto > 0)
        if sub_mask_gui.any() and sub_mask_auto.any():
            r_concat = np.concatenate([r_gui[sub_mask_gui], r_auto[sub_mask_auto]])
            y_lo = float(np.nanmin(r_concat)) * 0.5
            y_hi = float(np.nanmax(r_concat)) * 2.0

            iax = pax.inset_axes([0.56, 0.58, 0.40, 0.38])
            iax.set_facecolor("#FFFCF4")
            iax.errorbar(q_gui[sub_mask_gui], r_gui[sub_mask_gui],
                          yerr=dr_gui[sub_mask_gui],
                          fmt="o", ms=5, mew=0, color="#004B8D",
                          ecolor="#7EB0DB", elinewidth=0.7, capsize=0,
                          alpha=0.92)
            iax.errorbar(q_auto[sub_mask_auto], r_auto[sub_mask_auto],
                          yerr=dr_auto[sub_mask_auto] * 0.98,
                          fmt="s", ms=5, mew=0, color="#8C3A00",
                          ecolor="#EFA26A", elinewidth=0.7, capsize=0,
                          alpha=0.92)
            iax.set_xscale("log")
            iax.set_yscale("log")
            iax.set_xlim(q_cut_lo, q_cut_hi)
            iax.set_ylim(y_lo, y_hi)
            iax.grid(True, which="both", alpha=0.25)
            iax.tick_params(labelsize=9)
            iax.set_title("zoom — low-S/N gap",
                           fontsize=11, family=FAMILY, color="#8C3A00",
                           pad=4)
            for s in iax.spines.values():
                s.set_edgecolor("#E87722"); s.set_linewidth(1.5)

            # Connecting rectangle from main plot to inset.  loc1/loc2 pick
            # which corners of the inset get connected to the source rectangle.
            mark_inset(pax, iax, loc1=3, loc2=1, fc="none",
                        ec="#E87722", lw=1.2, linestyle="--")

    # summary box at bottom of right-panel
    info.add_patch(Rectangle((0.02, 0.01), 0.96, 0.05,
                              transform=info.transAxes,
                              facecolor="#002E5D", edgecolor="#001A35",
−33.6 KiB (280 KiB)
Loading image diff...
+1106 −1152

File changed.

Preview size limit exceeded, changes collapsed.