How to get a label in the ui panel, with the bpy.data.materials count?
len(bpy.data.materials) returns the number (int) of all materials in the file. To draw this number onto a custom panel, means that you have to pass it to the text argument of the label() call (string). 

In fact, you can either use str.format() or the old C-style formatting syntax for integers "%i" % number to pass the variable. A nice collection of examples here: https://pyformat.info/

# Number of all Materials in the .blend
layout.label(text="Materials: {}".format(len(bpy.data.materials))




Following example displays the number materials per file (Data.materials) as well as all materials in the current scene (custom object iteration). Layout code is ripped from How to create a custom UI?



import bpy

from bpy.props import (BoolProperty,
                       IntProperty,
                       PointerProperty
                       )

from bpy.types import (Panel,
                       PropertyGroup
                       )


# ------------------------------------------------------------------------
#    Scene Properties
# ------------------------------------------------------------------------

class MyProperties(PropertyGroup):

    my_bool: BoolProperty(
        name="Enable or Disable",
        description="A bool property",
        default = False
        )

    my_int: IntProperty(
        name = "Int Value",
        description="A integer property",
        default = 23,
        min = 10,
        max = 100
        )

# ------------------------------------------------------------------------
#    Panel in Object Mode
# ------------------------------------------------------------------------

class OBJECT_PT_CustomPanel(Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"   

    def scene_materials(self, context):
        mat_list_per_object = []
        for ob in context.scene.objects:
            if ob.type in ("MESH", "CURVE", "SURFACE", "FONT", "GPENCIL"):
                if ob.data.materials:
                    mat_list_per_object.append(ob.data.materials.items())
        # Flatten the list and return a set (unique)
        return set([i[0] for i in sum(mat_list_per_object, [])]) 

    @classmethod
    def poll(self,context):
        return context.object is not None

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        mytool = scene.my_tool

        # Custom Properties
        #layout.prop(mytool, "my_bool")
        #layout.prop(mytool, "my_int")

        # Number of Materials in File (bpy.data)
        layout.label(text="Number of Materials in this File: {}".format(
                len(bpy.data.materials))
            )

        # Number of materials (unique) per scene in context
        layout.label(text='Unique Materials in "{}": {}'.format(
                context.scene.name, 
                len(self.scene_materials(context)))
            )

        # Draw a list of materials per scene
        layout.separator()
        layout.label(text="List of Materials:")

        for i in self.scene_materials(context):
            layout.label(text=i)

        layout.separator()

# ------------------------------------------------------------------------
#    Registration
# ------------------------------------------------------------------------

classes = (
    MyProperties,
    OBJECT_PT_CustomPanel
)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)

    bpy.types.Scene.my_tool = PointerProperty(type=MyProperties)

def unregister():
    from bpy.utils import unregister_class
    for cls in reversed(classes):
        unregister_class(cls)
    del bpy.types.Scene.my_tool


if __name__ == "__main__":
    register()