ISTM that it is not a good idea to use the read_raw() method. I'd suggest to call read_bytes() instead. I don't have a UTG932/UTG963, so the following stuff is to a good part based on guesses.
My guesses are:
1. The UTG9x2 uses a simple USB/UART adapter, probably a CH340, not a USBTMC chip.
2. On Linux, you are using PyVisa together with the PyVisa-py backend.
I looked a bit into the source code of PyVisa and PyVisa-py, which turned out to become a sneak into a rabbit hole and I shyed away from following the whole call stack of read functions, beginning at
MessageBasedResource.read_raw() (in the package PyVisa), via
SerialSession.read() down to
Session.read() (the two latter methods are defined in the package PyVisa-py).
SCPI is mostly a text / line based protocol, so it is quite easy for an SCPI library to detect the end of a message sent from an SCPI device by searching for the hex values 0x0A and 0x0D )lone feed / carriage return). When you are reading binary data (like the screenshot), you can't use this check, since the values 0x0A and 0x0D may appear in the binary data. Hence you need another way to figure out if/when the message received from an SCPI device is complete. If you only have the RX/TX lines of a serial interface (or a simple TCP socket...), and if you do not have (or use – see below) any prior information about the length of the data you expect, only one way is left to figure out if the SCPI device has sent all data: A timeout.
Now let's have a quick look at the source code of the method
read_raw():
current Github status, i.e., commit 4849311)
https://github.com/pyvisa/pyvisa/blob/48493113f2df2106ffc664ab89eb644ebf935354/pyvisa/resources/messagebased.py.
read_raw(self, size: Optional[int] = None) is defined in line 411. The parameter "size" (which even does not need to be specified) is _not_ the number of bytes to read but just the chunk size for read calls of the transport layer. The doc string of the method does not explain how/when the read_raw() call terminates.
Let's look a bit deeper:
read_raw() is basically a "wrapper" for the method
_read_raw(), defined in line 430. This method calls
self.visalib.read(self.session, size) in a loop; the loop terminates when
self.visalib.read() returns a certain status. I don't know what this status is and how
visalib.read()
detects that a message is completed – I wasn't sure if I would find the way back if I would go down into this part of the rabbit hole, which is probably PyVisa-py in your case...
I guess that you can somewhere set a timeout value for the visalib.read() calls – but that's hidden somewhere quite deep in the rabbit hole

On the other hand: The data that the UTG9x2 sends back for the ":DISP?" command contains enough information that you don't have to rely on the obviously fragile read_raw() call. The first 10 Bytes or so tell you all you need: The length of the following binary data. The first byte should always be the '#' sign; the second byte is the number of digits of the following length information as an ASCII digit; the next N bytes (N being given in the second byte) contain the length of the binary data, again as ASCII digits. So you could try something like this:
sgen.write(":DISP?")
l1 = sgen.read_bytes(2)
if l1[0] != b'#':
raise RuntimeError(f'Unexpected response for :DISP? {l1!r}'
l2 = sgen.read_bytes(int(l1[1]))
bitmap = sgen.read_bytes(int(l2))
For debugging, add
print(l1) and
print(l2) to check if you got the ":DISP?" command right: As renaatd wrote in comment #428:
Just tried with "Display:Data?" in combination with read_binary_values, and it returns some data, but different from ":DISP?". Also tried with ":Disp?" and that causes a timeout. So I guess it's better to stick with ":DISP?".
So it makes sense to check if you get anything back for the command you sent to the device – it seems that these cheap SCPI devices often do not have the most robust SCPI parsers...
Final rant: It seems that you are not the only one who has problems using the read_raw() method, at least in the combination PyVisa and PyVisa-py. Have a look at
https://github.com/pyvisa/pyvisa-py/issues?q=is%3Aopen+read_rawA real highlight is this bug
https://github.com/pyvisa/pyvisa-py/issues/101Adding some diagnostics to TCPIPInstrSession.read(), this is what I see:
wanted 4096 bytes, read 1152057 bytes
want -1131577 more bytes
OK, this bug is a bit older – perhaps the maintainers just forgot to close it.
Having played a bit with PyVisa and PyVisa-py as well as NI-Visa as an electronics hobbyist (with professional software developer background), I came to the conclusions that it is seldom worth the effort to deal with all the Visa-related hassles. It can be easier to simply use a lower-level access to SCPI devices, be it plain TCP sockets for devices with an Ethernet interface, or a library like PySerial for the many devices with USB/UART adapters or real RS232 interfaces.
The situation may be different for people who are juggling with 10 or 20 SCPI devices in a professional application.