Drawing fractals with Turtle
For each shape, you have this kind of code to generate the movement "recipe":

axiom = ...
for _ in range(self.num):
    replacement = 'some fixed string'
    axiom = axiom.replace(pattern, replacement)
    axiom = axiom.replace(pattern2, replacement2)


This can be generalized with a helper function that takes as parameters axiom and a list of pattern-replacement pairs. All shapes will be able to use this helper and thereby reduce duplication.

The execution of the movement commands is also repetitive. The code for the most complex shape would be able to draw all the simpler​ shapes, with a single parameter of the turn degrees.