There are many reasons why you may want to programmatically create a category in Magento 2. Your blog posts, brands that can be redirects to CMS pages, or even dynamically generated marketing categories can all be created with code. Rather than burden an end user with creating these things manually, let's script it.

Here is a simple example of a Data Upgrade script. This script creates a category under the default category using some parameters you define. The example below is simple so it's easier to understand, but with some customization data can be accepted from a CSV file or other data source.

/**
 * Create category
 */
protected function createCategory()
{
    $urlKey = 'blog';
    $row = [
        'name'            => 'Blog',
        'url_key'         => $urlKey,
        'active'          => 1,
        'is_anchor'       => 1,
        'include_in_menu' => 1,
        'display_mode'    => 'PAGE', // [PRODUCTS, PAGE, PRODUCTS_AND_PAGE]
    ];

    /** @var Category $category */
    $category = $this->categoryFactory->create();
    $category = $category->loadByAttribute('url_key', $urlKey);

    if (!$category) {
        // Set admin area
        $this->state->setAreaCode('adminhtml');
        $store = $this->storeManager->getStore(Store::ADMIN_CODE);
        $this->storeManager->setCurrentStore($store->getCode());

        $parentId = $this->defaultCategoryHelper->getId();
        $parentCategory = $this->categoryFactory->create();
        $parentCategory = $parentCategory->load($parentId);

        $data = [
            'parent_id'       => $parentCategory->getId(),
            'name'            => $row['name'],
            'is_active'       => $row['active'],
            'is_anchor'       => $row['is_anchor'],
            'include_in_menu' => $row['include_in_menu'],
            'url_key'         => $row['url_key'],
        ];

        /** @var Category $category */
        $category = $this->categoryFactory->create();
        $category
            ->setData($data)
            ->setAttributeSetId($category->getDefaultAttributeSetId());
        $this->setAdditionalData($row, $category);
        $this->categoryRepository->save($category);
    }
}

Position, Display Mode, Page Layout, Layout Update should be set as Additional Data.

/**
 * @param array    $row
 * @param Category $category
 *
 * @return void
 */
protected function setAdditionalData($row, $category)
{
    $additionalAttributes = [
        'position',
        'display_mode',
        'page_layout',
        'custom_layout_update',
    ];
    foreach ($additionalAttributes as $categoryAttribute) {
        if (!empty($row[$categoryAttribute])) {
            $attributeData = [$categoryAttribute => $row[$categoryAttribute]];
            $category->addData($attributeData);
        }
    }
}

And finally, here is the full script if you'd like to copy, paste and play around with this in your own environment.

namespace RocketWeb\UpgradeSamples\Setup;

use Magento\Catalog\Helper\DefaultCategory;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\CategoryFactory;
use Magento\Catalog\Model\CategoryRepository;
use Magento\Framework\App\State;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManager;

class UpgradeData implements UpgradeDataInterface
{
    /**
     * @var StoreManager
     */
    protected $storeManager;

    /**
     * @var DefaultCategory
     */
    protected $defaultCategoryHelper;

    /**
     * @var CategoryFactory
     */
    protected $categoryFactory;

    /**
     * @var CategoryRepository
     */
    protected $categoryRepository;

    /**
     * @var State
     */
    protected $state;

    /**
     * UpgradeData constructor.
     *
     * @param StoreManager       $storeManager
     * @param DefaultCategory    $defaultCategoryHelper
     * @param CategoryFactory    $categoryFactory
     * @param CategoryRepository $categoryRepository
     * @param State              $state
     */
    public function __construct(
        StoreManager $storeManager,
        DefaultCategory $defaultCategoryHelper,
        CategoryFactory $categoryFactory,
        CategoryRepository $categoryRepository,
        State $state
    ) {
        $this->storeManager = $storeManager;
        $this->defaultCategoryHelper = $defaultCategoryHelper;
        $this->categoryFactory = $categoryFactory;
        $this->categoryRepository = $categoryRepository;
        $this->state = $state;
    }

    /**
     * {@inheritdoc}
     */
    public function upgrade(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        if (version_compare($context->getVersion(), '0.0.1') createCategory();
        }

        $setup->endSetup();
    }

    /**
     * Create category
     */
    protected function createCategory()
    {
        $urlKey = 'blog';
        $row = [
            'name'            => 'Blog',
            'url_key'         => $urlKey,
            'active'          => 1,
            'is_anchor'       => 1,
            'include_in_menu' => 1,
            'display_mode'    => 'PAGE', // [PRODUCTS, PAGE, PRODUCTS_AND_PAGE]
        ];

        /** @var Category $category */
        $category = $this->categoryFactory->create();
        $category = $category->loadByAttribute('url_key', $urlKey);

        if (!$category) {
            // Set admin area
            $this->state->setAreaCode('adminhtml');
            $store = $this->storeManager->getStore(Store::ADMIN_CODE);
            $this->storeManager->setCurrentStore($store->getCode());

            $parentId = $this->defaultCategoryHelper->getId();
            $parentCategory = $this->categoryFactory->create();
            $parentCategory = $parentCategory->load($parentId);

            $data = [
                'parent_id'       => $parentCategory->getId(),
                'name'            => $row['name'],
                'is_active'       => $row['active'],
                'is_anchor'       => $row['is_anchor'],
                'include_in_menu' => $row['include_in_menu'],
                'url_key'         => $row['url_key'],
            ];

            /** @var Category $category */
            $category = $this->categoryFactory->create();
            $category
                ->setData($data)
                ->setAttributeSetId($category->getDefaultAttributeSetId());
            $this->setAdditionalData($row, $category);
            $this->categoryRepository->save($category);
        }
    }

    /**
     * @param array    $row
     * @param Category $category
     *
     * @return void
     */
    protected function setAdditionalData($row, $category)
    {
        $additionalAttributes = [
            'position',
            'display_mode',
            'page_layout',
            'custom_layout_update',
        ];
        foreach ($additionalAttributes as $categoryAttribute) {
            if (!empty($row[$categoryAttribute])) {
                $attributeData = [$categoryAttribute => $row[$categoryAttribute]];
                $category->addData($attributeData);
            }
        }
    }
}