Here is an example set-up with observed response just 2(1)10 as reported.
The Stata code should seem fairly transparent even to those who have never used it. gen
means generate
.
clear
set obs 500
set seed 2803
gen y = round(rnormal(6, 1.5), 1)
gen x1 = rnormal()
gen x2 = rnormal()
regress y x1 x2
rvfplot , mla(y) mlabpos(0) ms(none)
I'm just regressing the response against Gaussian noise in this example, but the features noticeable on this plot are generic.
For each distinct observed response, there is a line
residual $=$ observed $-$ fitted
So, for observed $= 7$, all those points lie on the line
residual $= 7 -$ fitted
and the slope with fitted is negative (here, where there is no standardization or other adjustment of fitted, it is exactly $-1$).
That's always true. Naturally at one extreme if each value of the response is (literally) unique, each line is represented by just a single point and won't be discernible as such. But whenever there are just a few distinct values, as here, the lines will be discernible.
Plotting the numeric values of the response is not standard but surely a useful option to make clear what is happening. If your favourite software won't allow it, you need to change to a new favourite.
Incidentally, I prefer to see the actual values of residual and fitted on these graphs.
Not the question, but with small discrete responses it's worth keeping tracking of whether the model is predicting impossible values. Plain linear regression may be a poor idea for such data.