2025, Nov 03 05:00

Fixing Python memory_graph show() when only one PDF snapshot appears: unique outfile names and viewer tips

Troubleshoot memory_graph show() showing a single PDF. Learn why viewer locking occurs, how render() differs, and how unique outfile names ensure snapshots.

When you inspect Python memory with memory_graph and expect multiple PDF snapshots to appear one after another, calling show() twice can be misleading. In practice, many users see only the first display sticking, or only the final state flashing into view. Meanwhile, writing images with render() behaves as expected. Let’s unpack why this happens and how to make your visualizations predictable.

The problem, reproduced

The following example generates two consecutive views in a PDF viewer. The list is aliased, then mutated, and show() is called before and after the change. The intention is to see two distinct states.

import memory_graph as memg
vals = [4, 3, 2]
mirror = vals
memg.show(locals())
mirror += [1]
memg.show(locals())

Instead of two views, the viewer often stops on the first PDF file or replaces it so quickly that only the last state remains visible.

Why render() seems fine

Writing static images with explicit filenames works consistently because the outputs differ and are not re-used by the viewer.

import memory_graph as memg
nums = [4, 3, 2]
ref = nums
memg.render(locals(), 'snapshot1.png')
ref += [1]
memg.render(locals(), 'snapshot2.png')

Two separate files are created, and nothing in the viewer has to be refreshed in place.

What’s really happening

On Linux Mint it typically shows only the last file. The first snapshot opens, but the next call reuses the same viewer window and replaces the content. The switch is so fast that the initial state is effectively invisible. According to the source code, show() uses render() under the hood and generates files with the same names, so the external viewer simply refreshes what it already has open rather than spawning a second window. This aligns with another observed behavior: when a PDF viewer locks the file it has opened, updates from the second call cannot replace the content, which makes the display appear stuck on the first PDF. In follow-up testing, Adobe Acrobat Reader exhibited this locking behavior, while Sumatra PDF allowed updates as expected.

The fix: give each show() a unique outfile

To ensure you can see both states side by side or in separate viewer windows, give each call a different output filename.

import memory_graph as memg
items = [4, 3, 2]
shared = items
memg.show(locals(), outfile="view_1.pdf")
shared += [1]
memg.show(locals(), outfile="view_2.pdf")

With distinct PDF names, you get two displays. This matches the observation that adding outfile="file.pdf" with different names shows both files, and confirms that the external viewer is the deciding factor.

Why this matters

When exploring object aliasing, mutability, and reference graphs, you often need to capture a sequence of states. Tooling should not distort what you see. Understanding that the viewer may reuse or lock the same filename helps avoid false conclusions about the memory state itself. Choosing a viewer that does not block updates, or producing uniquely named outputs, ensures reliable introspection.

Practical takeaways

If you rely on show(), specify a unique outfile for each snapshot to get multiple windows or sequential files that won’t overwrite one another. If your viewer prevents updates to an open PDF, switch to a viewer that allows live refreshes; in testing, Sumatra PDF worked where Adobe Acrobat Reader blocked updates. If you only need artifacts for later inspection, render() to unique image filenames is a straightforward option. And if in doubt about how show() generates its outputs, consult the project’s source: it indicates show() builds on render(), which explains the same-name behavior and the resulting viewer refresh.

The short version: your code is correct, the interaction with the external PDF viewer is the culprit. Use unique filenames or a viewer that doesn’t lock the file, and your memory graphs will display exactly as intended.

The article is based on a question from StackOverflow by user31005948 and an answer by furas.