Creating regularly spaced points inside polygon based on attribute value using QGIS?

May be a other way inspiring by the answer of Sarath SRK :

  1. Centroid of polygons
  2. Buffer employing an expression with the square and to adapt with your scale : i.e (1000*(sqrt("Frogs"+"Cats"+"Diplodocs" )/2))+1 and Segment=1, End cap style=Square
  3. New Grid point with a spacing coherent with the scale of the buffer.
  4. Delete point that don't intersect with the buffer layer (select by location)
  5. join attribut by location (Attribut of the buffer or the original polygons)

Yet, you will have something like this enter image description here

  1. Use à graphical modeler to create a new field with the commande "@row_number" enter image description here

  2. Execute the model with an iteration on the buffer layer enter image description here

  3. Merge all new layer

  4. Delete all the point with an ID_pt field bigger than the sum of your field ("Frogs"+"Cats"+"Diplodocs" )

  5. Categorise with rules (i.e.
    • "ID_pt" <= "Frogs"
    • "ID_pt" > "Frogs" and "ID_pt" <= ("Cats" + "Frogs" )
    • "ID_pt" > ("Cats" +"Frogs") and "ID_pt" <= ("Cats" + "Frogs"+ "Diplodocs" ) enter image description here

QGIS 3 comes with a new displacement method in the cluster renderer called grid. Looks like this is pretty much what you need. Just create the number of desired points at the centroid of your polygon.

enter image description here

I am not aware of a method to generate the points only with a gui tool, but a relatively simple python script should do that.

with edit(point_layer):
    for polygon_feature in polygon_layer.getFeatures():
        point_feature = QgsFeature(point_layer.fields())
        point_feature.setGeometry(polygon_feature.geometry().centroid())

        point_feature['type'] = 'Frog'
        for i in range(polygon_feature['Frogs']):
            point_layer.addFeature(point_feature)

        point_feature['type'] = 'Cat'
        for i in range(polygon_feature['Cats']):
            point_layer.addFeature(point_feature)

        point_feature['type'] = 'Diplodoc'
        for i in range(polygon_feature['Diplodocs']):
            point_layer.addFeature(point_feature)

If you want to go crazy, wrap that in a custom processing algorithm.