The BIAS positive for the HMC5883L are different for X&Y than Z, the field generated for X&Y are 1.16 Gauss, Z have 1.08 Gauss (that is 7% difference) according to datasheet.
This is a method to compensate:
magCal[ROLL] = 1160.0 / abs(magADC[ROLL]);
magCal[PITCH] = 1160.0 / abs(magADC[PITCH]);
magCal[YAW] = 1080.0 / abs(magADC[YAW]);
Also they are different for HMC5843 that is 0.55 gauss for x,y,z.
The perfect calibration can be obtained in this way:
- point to the north 3d in your zone (for europe point north and down, it is near 45 degree down to earth)

- rotate yaw 360 degree (x,y calibration)
- rotate pitch 360 degree (y z calibration)
- point multicopter west
- roll 360 degree (x z calibration)
Why the 3 value taken from MAG are named roll, pitch, yaw instead of x,y,z?