Quoting from QCPDataContainer documentation:
The data can be accessed with the provided const iterators (constBegin, constEnd). If it is necessary to alter existing data in-place, the non-const iterators can be used (begin, end). Changing data members that are not the sort key (for most data types called key) is safe from the container's perspective.
Great care must be taken however if the sort key is modified through the non-const iterators. For performance reasons, the iterators don't automatically cause a re-sorting upon their manipulation. It is thus the responsibility of the user to leave the container in a sorted state when finished with the data manipulation, before calling any other methods on the container. A complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling sort. Failing to do so can not be detected by the container efficiently and will cause both rendering artifacts and potential data loss.
(ui->plot->graph(0)->data()->begin()+i) you retrieve the mutable iterator of the i-th data point (starting at 0). You can access and modify its members as usual by dereferencing:
(customPlot->graph(0)->data()->begin()+i)->value = 3.14;
I don't agree that adding a setData would help – QCPDataContainer is iterator based, so this access pattern is the expectable way to do it, if you need data-point access via integer index. Note that accessing data via the floating-point key always has the issue of possible floating-point ambiguity/precision, and is thus only reasonable if you know exactly what you're doing and where your keys come from that you use for access (e.g. not from a calculation).