Skip to content

Commit

Permalink
[SVG] Noise hack and font fix (#3076)
Browse files Browse the repository at this point in the history
 - Specify the font. This should not be a change for viewing in Jupyter notebook but fixes opening the svg data in e.g. inkscape where the default font is different and the boxes aren't the right size
 - Don't display virtual tags (for noise) xref #2905
  • Loading branch information
mpharrigan authored Jun 9, 2020
1 parent e1e0038 commit 20fb717
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
29 changes: 20 additions & 9 deletions cirq/contrib/svg/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,25 @@
import cirq

QBLUE = '#1967d2'
FONT = "Arial"


def fixup_text(text: str):
if '\n' in text:
return '?'
if '[<virtual>]' in text:
# https://github.com/quantumlib/Cirq/issues/2905
# TODO: escape angle brackets when you actually want to display tags
return text.replace('[<virtual>]', '') # coverage: ignore
if '[cirq.VirtualTag()]' in text:
# https://github.com/quantumlib/Cirq/issues/2905
return text.replace('[cirq.VirtualTag()]', '')
return text


def _get_text_width(t: str) -> float:
if '\n' in t:
return _get_text_width('?')
tp = matplotlib.textpath.TextPath((0, 0), t, size=14, prop='Arial')
t = fixup_text(t)
tp = matplotlib.textpath.TextPath((0, 0), t, size=14, prop=FONT)
bb = tp.get_extents()
return bb.width + 10

Expand All @@ -30,7 +43,8 @@ def _rect(x: float,
def _text(x: float, y: float, text: str, fontsize: int = 14):
"""Draw SVG <text> text."""
return f'<text x="{x}" y="{y}" dominant-baseline="middle" ' \
f'text-anchor="middle" font-size="{fontsize}px">{text}</text>'
f'text-anchor="middle" font-size="{fontsize}px" ' \
f'font-family="{FONT}">{text}</text>'


def _fit_horizontal(tdd: 'cirq.TextDiagramDrawer',
Expand Down Expand Up @@ -208,13 +222,10 @@ def tdd_to_svg(
if v.text == '×':
t += _text(x, y + 3, '×', fontsize=40)
continue
if '\n' in v.text:
t += _rect(boxx, boxy, boxwidth, boxheight)
t += _text(x, y, '?', fontsize=18)
continue

v_text = fixup_text(v.text)
t += _rect(boxx, boxy, boxwidth, boxheight)
t += _text(x, y, v.text, fontsize=14 if len(v.text) > 1 else 18)
t += _text(x, y, v_text, fontsize=14 if len(v_text) > 1 else 18)

t += '</svg>'
return t
Expand Down
9 changes: 9 additions & 0 deletions cirq/contrib/svg/svg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ def test_svg():
assert '</svg>' in svg_text


def test_svg_noise():
noise_model = cirq.ConstantQubitNoiseModel(cirq.DepolarizingChannel(p=1e-3))
q = cirq.LineQubit(0)
circuit = cirq.Circuit(cirq.X(q))
circuit = cirq.Circuit(noise_model.noisy_moments(circuit.moments, [q]))
svg = circuit_to_svg(circuit)
assert '>D(0.001)</text>' in svg


def test_validation():
with pytest.raises(ValueError):
circuit_to_svg(cirq.Circuit())
Expand Down

0 comments on commit 20fb717

Please sign in to comment.