There really is no difference ... what happens because you accept what makes it very small (your path is very small):

Look at the little boxes
... and scaling it extremely large and telling the layout to round to the nearest whole pixel via UseLayoutRounding
the reason the result is unreliable is because Path scales independently of the Canvas , since it does not actually compose its contents. Therefore, when one of your paths falls on an uneven pixel border (which can happen at some screen resolutions, and not at others), it is rounded to the nearest virtual pixel inside an unscaled canvas, and it becomes scaled from the Viewbox and then rounded to the nearest whole pixel (using the same Viewbox scale defined by Canvas scaling), exacerbating the rounding error. You can see this more easily if you turn off StackPanel.Background (transparent by default), set the Canvas.Background parameter to green and type the opacity of the stroke color:

you can see that rounding the path is different from the canvas
Thus, you need to disable UseLayoutRounding so that decimal points are executed in the operation or simplified so that errors do not occur.
For example, if you allow the paths to scale themselves by removing the inappropriate and extra fixed-size canvas and setting Path.Stretch = Uniform , you get:
<StackPanel Background="Red" Width="400" UseLayoutRounding="True"> <StackPanel.Resources> <Style TargetType="Viewbox"> <Setter Property="Height" Value="400" /> <Setter Property="Margin" Value="0,0,0,50" /> </Style> <Style TargetType="Path"> <Setter Property="Stroke" Value="Blue" /> <Setter Property="StrokeThickness" Value="2" /> <Setter Property="Stretch" Value="Uniform" /> </Style> </StackPanel.Resources> <Viewbox> <Path Data="M 1,1 h 3 v 3 h -3 z" /> </Viewbox> <Viewbox> <Path Data="M 1,1 h 4 v 4 h -4 z" /> </Viewbox> </StackPanel>
, as a result: 
perhaps what you really were looking for
However, if it was more simplified, and in fact you have several paths that you intended to insert into your Canvas , I suggest you use a container that actually makes its own layout, the obvious choice is Grid so you still You can scale yourself using the Grid , holding them in lock mode ( Canvas will not place your children). The code will look like this:
<StackPanel Background="Red" Width="400" UseLayoutRounding="True"> <StackPanel.Resources> <Style TargetType="Viewbox"> <Setter Property="Height" Value="400" /> <Setter Property="Margin" Value="0,0,0,50" /> </Style> <Style TargetType="Path"> <Setter Property="Stroke" Value="Blue" /> <Setter Property="StrokeThickness" Value="2" /> <Setter Property="Stretch" Value="Uniform" /> </Style> </StackPanel.Resources> <Viewbox> <Grid Width="5" Height="5"> <Path Data="M 1,1 h 3 v 3 h -3 z" /> </Grid> </Viewbox> <Viewbox> <Grid Width="6" Height="6"> <Path Data="M 1,1 h 4 v 4 h -4 z" /> </Grid> </Viewbox> </StackPanel>
, and the result is identical to the result without an additional container
hope this helps -ck