This is textbook stuff.
That’s good for 0-20mA. But the OP requested 4-20mA. But, you could get away with that by not using the full DAC range [I’m including the PWM technique under that *DAC umbrella*]. But, if you want the full precision available:
The above is more concepuized-- basically two current sinks, one at a constant 4mA, and the other a Voltage to Current translator [0-5V to 0-16mA]. The combination creates a 4 to 20mA transmitter, with a linear voltage to current transfer. This one is shown with a simple PWM low-pass filter.
And, this one is a more practical diagram. The Op-Amps can be any common mode to ground, single supply device that can handle whatever voltage is in use, such as the LM324 or the LM358. I forgot to show the supply lines on the op-amps. Tie V- to ground, and V+ to 30V or whatever voltage is the VHigh supply you choose.
The transistors can be 2N3904, or one with a higher max CE voltage, like: MPS06
Typically, a 4-20mA transmitter has a fairly large voltage range going as high as 36V, with 12 to 30V typical. Basically, this voltage needs to be high enough to allow 20mA to flow in the loop–a level that is determined by the total expected maximum resistance in the current loop. BUT, check to see if the device you intend to drive has a max voltage rating, and, at least, comply with that.
For greater precision and probably better response, I suggest using a serial DAC, like the following:
The same page has links to Arduino sample code.
The 10k + 10k voltage divider that follows the DAC is there to reduce the top voltage so there is a greater voltage span in the current loop. Also, it keeps the input voltage within the input range.
And, you will need to incorporate some variable resistors in there, to calibrate the thing to exactly 4mA at 0V in and 20mA at 2.5V in.
Also wise to use stable resistors [e.g. 1% metal film]. And quality trim pots. And, maybe some sort of protection circuitry on the 4-20mA output.
And, if this will be driving some sort of expensive or hard to replace device, then do this at your own risk!
Or, purchase something like this: https://www.ebay.com/itm/Arduino-4-20mA-Current-Loop-Transmitter-XTR116U-I2C-Interface-industry-standard/173326373205?hash=item285b0e9155%3Ag%3AL4IAAOSwwcdbALKV&_sacat=0&_nkw=arduino+shield+4-20ma+transmitter&_from=R40&rt=nc&_trksid=m570.l1313
But, good luck getting it to work.
Then there’s this: https://ncd.io/interfacing-isolated-4-20ma-current-loop-transmitter-arduino/