Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to latex drawer to enable label passthrough #3172

Closed
wants to merge 5 commits into from

Conversation

mtreinish
Copy link
Member

Summary

This commit adds a new flag latex_labels to the circuit_drawer for use
with the latex and latex_source drawer. When it is set to true it
disables the pylatexenc conversion from unicode input to a latex
encoding. This enables users who want to manual create gate names that
are properly latex encoded (for example to have gate names with
subscripts) to do so.

Details and comments

Fixes #3171

@mtreinish mtreinish added the Changelog: New Feature Include in the "Added" section of the changelog label Sep 30, 2019
This commit adds a new flag latex_labels to the circuit_drawer for use
with the latex and latex_source drawer. When it is set to true it
disables the pylatexenc conversion from unicode input to a latex
encoding. This enables users who want to manual create gate names that
are properly latex encoded (for example to have gate names with
subscripts) to do so.

Fixes Qiskit#3171
Copy link
Contributor

@maddy-tod maddy-tod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, thank you! Is there anyway you could include an example image in the release notes? Alternatively, could you add some images to this PR so that people can see what can be done?

@@ -560,8 +560,8 @@ def qasm(self):

def draw(self, scale=0.7, filename=None, style=None, output=None,
interactive=False, line_length=None, plot_barriers=True,
reverse_bits=False, justify=None, idle_wires=True, vertical_compression='medium',
with_layout=True, fold=None):
reverse_bits=False, justify=None, vertical_compression='medium', idle_wires=True,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked the source of this diff and it looks #3108 accidentally changed this (my rebase reverted it back to the previous order). See the last release: https://github.com/Qiskit/qiskit-terra/blob/0.9.0/qiskit/circuit/quantumcircuit.py#L534

This actually fixes a potentially breaking change because the order of kwargs is part of the api. (unless we specified a ** to indicate keyword only, which we can't introduce for the same backwards compat concerns)

@mtreinish
Copy link
Member Author

mtreinish commented Oct 7, 2019

@maddy-tod including images in the release notes is problematic for right now given how I have to manually copy over generated rst to the meta-repo at release time to get them published properly. It's an extra thing to keep track of and manually do as part of that process which is kinda of error prone. I have automating the release notes process as a near term todo and when I start writing that (likely as a sphinx extension based on the one included with reno) I'll make sure to factor in release note images into that. In the meantime I'll generate a couple images for here so people can see a simple case of how to use this.

@mtreinish
Copy link
Member Author

mtreinish commented Oct 7, 2019

from qiskit import visualization
from qiskit import circuit
  
qc = circuit.QuantumCircuit(1)
inst = circuit.Instruction('foo_{\gamma}', 1, 0, [])
qc.append(inst, [0])
  
visualization.circuit_drawer(qc, output='latex', filename='latex_enc.png')

latex_enc

visualization.circuit_drawer(qc, output='latex', filename='latex_noenc.png',
                             latex_labels=True)

latex_noenc

qc = circuit.QuantumCircuit(1)
inst = circuit.Instruction('foo_{γ}', 1, 0, [])
qc.append(inst, [0])
visualization.circuit_drawer(qc, output='latex', filename='latex_enc2.png')

latex_enc2

(This will raise an error with latex_labels set from latex because γ is not a valid character for the latex)

@ajavadia
Copy link
Member

ajavadia commented Oct 7, 2019 via email

@mtreinish
Copy link
Member Author

mtreinish commented Oct 7, 2019

Is there a way to indicate whether you want an underscore escaped or not based on the syntax you use in the gate label? Maybe something with curly brackets around the underscore or something? That would be preferable for two reasons: 1- not introducing yet another arg to circuit.draw(), especially since this one only affects one specific drawer, whereas the other args are more general 2- being able to mix the two, i.e have gates with “” and subscript in their names

On Oct 7, 2019, at 2:30 PM, Matthew Treinish @.***> wrote: from qiskit import visualization from qiskit import circuit qc = circuit.QuantumCircuit(1) inst = circuit.Instruction('foo
{\gamma}', 1, 0, []) qc.append(inst, [0]) visualization.circuit_drawer(qc, output='latex', filename='latex_enc.png') visualization.circuit_drawer(qc, output='latex', filename='latex_noenc.png', latex_labels=True) qc = circuit.QuantumCircuit(1) inst = circuit.Instruction('foo_{γ}', 1, 0, []) qc.append(inst, [0]) visualization.circuit_drawer(qc, output='latex', filename='latex_enc2.png') — You are receiving this because your review was requested. Reply to this email directly, view it on GitHub, or mute the thread.

The problem is that the instruction name field is string object and can contain any utf8 characters. When converting the circuit to latex for custom gate labels we really only have a binary choice when writing out the latex for that custom instruction to the latex file, either use that string verbatim in the latex (which enables the end user to use native latex formatting) or to coerce it into the latex format, which is the current unconditional behavior. Originally we passed it verbatim and that was problematic for most users because a common things was to pass strings like custom_gate or my_gate which would subscript the g which is why we added the latex form conversion to escape and convert unicode to latex.

Trying to be more clever about this will just cause more subtle edge cases then what we have now by forcing the utf8->latex conversion. Like we could do what mpl (this is an internal mpl thing not something the drawer does), and take a string between two $ characters and treat that as latex math mode. The implementation for that would be in the latex module to detect a leading and trailing $, strip those characters and pass that remainder verbatim, else utf8tolatex. But then it gets weird, because what if someone wants the dollar signs in their string?

@ajavadia
Copy link
Member

ajavadia commented Oct 8, 2019

Oh if mpl does that then it's easy, we just replicate their interface.
Like this:

from qiskit import *
from qiskit.circuit import *
circ = QuantumCircuit(2)
circ.h([0, 1])
circ.append(Gate(name='my_gate', num_qubits=1, params=[0]), [0])
circ.append(Gate(name='my_gate$_2$', num_qubits=1, params=[0]), [1])

image

We can mix both underscore and subscripts which seems nice to me and avoids adding the latex-specific flag to top-level .draw().

Also having dollar in the name is weird but it's possible. You can just escape the dollar:

circ.append(Gate(name='\$50_gate', num_qubits=1, params=[0]), [1])

image

@mtreinish
Copy link
Member Author

Yes, I know how the mpl syntax works. The difference here is that matplotlib is doing that parsing and rendering for us under the covers. If we want to duplicate that syntax for the latex drawer we'll have to implement it ourselves, by parsing the string, determining which portions are either to be passed to utf8tolatex or not. Then reassemble the string from those parts after it goes through the conversion. That's where the complexity around $ comes in because if we go with escaping it that has to be implemented in the regex we use. It's doable, but more work and more error prone than this. But, I'll play around with it locally and see what I can come up with.

@mtreinish
Copy link
Member Author

@ajavadia I opened up: #3224 to implement this using the same syntax as mpl's mathtext.

I'm closing this as #3224 now supersedes this.

@mtreinish mtreinish closed this Oct 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow formatting in names of custom gates
3 participants