Repository: Qiskit/qiskit

Issue:
Circuit drawers do not handle complex values
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**:
- **Python version**:
- **Operating system**:

### What is the current behavior?
```python
ket = np.array([0.7071067811865476, 0, 0, 1j*0.7071067811865476])
qc = QuantumCircuit(2)
qc.initialize(ket, [0, 1])
qc.draw()
```
```
        ┌────────────────────────────┐
q_0: |0>┤0                           ├
        │  initialize(0.70711,0,0,0) │
q_1: |0>┤1                           ├
        └────────────────────────────┘
```
same for MPL

<img width="221" alt="Screen Shot 2019-12-19 at 5 15 36 PM" src="https://user-images.githubusercontent.com/1249193/71214390-2da3ef80-2283-11ea-945f-6c8bc5786e96.png">




### Steps to reproduce the problem



### What is the expected behavior?



### Suggested solutions





Discussion:
I would like to take this up. Basically I would be looking into .../qiskit/visualization/tools/pi_check.py

I will be fixing this warning in pi_check.py

![image](https://user-images.githubusercontent.com/6925028/71643984-bdd03480-2c86-11ea-8471-ef649fc44ae6.png)


Resolving patch:
diff --git a/qiskit/visualization/tools/pi_check.py b/qiskit/visualization/tools/pi_check.py
--- a/qiskit/visualization/tools/pi_check.py
+++ b/qiskit/visualization/tools/pi_check.py
@@ -48,81 +48,89 @@ def pi_check(inpt, eps=1e-6, output='text', ndigits=5):
         return str(inpt)
     elif isinstance(inpt, str):
         return inpt
-    inpt = float(inpt)
-    if abs(inpt) < 1e-14:
-        return str(0)
-    val = inpt / np.pi
-
-    if output == 'text':
-        pi = 'pi'
-    elif output == 'latex':
-        pi = '\\pi'
-    elif output == 'mpl':
-        pi = '$\\pi$'
-    else:
-        raise QiskitError('pi_check parameter output should be text, latex, or mpl')
-
-    if abs(val) >= 1:
-        if abs(val % 1) < eps:
+
+    def normalize(single_inpt):
+        if abs(single_inpt) < 1e-14:
+            return '0'
+        val = single_inpt / np.pi
+        if output == 'text':
+            pi = 'pi'
+        elif output == 'latex':
+            pi = '\\pi'
+        elif output == 'mpl':
+            pi = '$\\pi$'
+        else:
+            raise QiskitError('pi_check parameter output should be text, latex, or mpl')
+        if abs(val) >= 1:
+            if abs(val % 1) < eps:
+                val = int(round(val))
+                if val == 1:
+                    str_out = '{}'.format(pi)
+                elif val == -1:
+                    str_out = '-{}'.format(pi)
+                else:
+                    str_out = '{}{}'.format(val, pi)
+                return str_out
+
+        val = np.pi / single_inpt
+        if abs(abs(val) - abs(round(val))) < eps:
             val = int(round(val))
-            if val == 1:
-                str_out = '{}'.format(pi)
-            elif val == -1:
-                str_out = '-{}'.format(pi)
+            if val > 0:
+                if output == 'latex':
+                    str_out = '\\frac{%s}{%s}' % (pi, abs(val))
+                else:
+                    str_out = '{}/{}'.format(pi, val)
             else:
-                str_out = '{}{}'.format(val, pi)
+                if output == 'latex':
+                    str_out = '\\frac{-%s}{%s}' % (pi, abs(val))
+                else:
+                    str_out = '-{}/{}'.format(pi, abs(val))
             return str_out
 
-    val = np.pi / inpt
-    if abs(abs(val) - abs(round(val))) < eps:
-        val = int(round(val))
-        if val > 0:
-            if output == 'latex':
-                str_out = '\\frac{%s}{%s}' % (pi, abs(val))
-            else:
-                str_out = '{}/{}'.format(pi, val)
-        else:
-            if output == 'latex':
-                str_out = '\\frac{-%s}{%s}' % (pi, abs(val))
-            else:
-                str_out = '-{}/{}'.format(pi, abs(val))
-        return str_out
+        # Look for all fracs in 8
+        abs_val = abs(single_inpt)
+        frac = np.where(np.abs(abs_val - FRAC_MESH) < 1e-8)
+        if frac[0].shape[0]:
+            numer = int(frac[1][0]) + 1
+            denom = int(frac[0][0]) + 1
+            if single_inpt < 0:
+                numer *= -1
 
-    # Look for all fracs in 8
-    abs_val = abs(inpt)
-    frac = np.where(np.abs(abs_val - FRAC_MESH) < 1e-8)
-    if frac[0].shape[0]:
-        numer = int(frac[1][0]) + 1
-        denom = int(frac[0][0]) + 1
-        if inpt < 0:
-            numer *= -1
-
-        if numer == 1 and denom == 1:
-            str_out = '{}'.format(pi)
-        elif numer == -1 and denom == 1:
-            str_out = '-{}'.format(pi)
-        elif numer == 1:
-            if output == 'latex':
-                str_out = '\\frac{%s}{%s}' % (pi, denom)
-            else:
-                str_out = '{}/{}'.format(pi, denom)
-        elif numer == -1:
-            if output == 'latex':
-                str_out = '\\frac{-%s}{%s}' % (pi, denom)
-            else:
-                str_out = '-{}/{}'.format(pi, denom)
-        elif denom == 1:
-            if output == 'latex':
-                str_out = '\\frac{%s}{%s}' % (numer, pi)
-            else:
-                str_out = '{}/{}'.format(numer, pi)
-        else:
-            if output == 'latex':
-                str_out = '\\frac{%s%s}{%s}' % (numer, pi, denom)
+            if numer == 1 and denom == 1:
+                str_out = '{}'.format(pi)
+            elif numer == -1 and denom == 1:
+                str_out = '-{}'.format(pi)
+            elif numer == 1:
+                if output == 'latex':
+                    str_out = '\\frac{%s}{%s}' % (pi, denom)
+                else:
+                    str_out = '{}/{}'.format(pi, denom)
+            elif numer == -1:
+                if output == 'latex':
+                    str_out = '\\frac{-%s}{%s}' % (pi, denom)
+                else:
+                    str_out = '-{}/{}'.format(pi, denom)
+            elif denom == 1:
+                if output == 'latex':
+                    str_out = '\\frac{%s}{%s}' % (numer, pi)
+                else:
+                    str_out = '{}/{}'.format(numer, pi)
             else:
-                str_out = '{}{}/{}'.format(numer, pi, denom)
+                if output == 'latex':
+                    str_out = '\\frac{%s%s}{%s}' % (numer, pi, denom)
+                else:
+                    str_out = '{}{}/{}'.format(numer, pi, denom)
 
+            return str_out
+        # nothing found
+        str_out = '%.{}g'.format(ndigits) % single_inpt
         return str_out
-    # nothing found
-    str_out = '%.{}g'.format(ndigits) % inpt
-    return str_out
+
+    complex_inpt = complex(inpt)
+    real, imag = map(normalize, [complex_inpt.real, complex_inpt.imag])
+
+    if real == '0' and imag != '0':
+        return imag + 'j'
+    elif real != 0 and imag != '0':
+        return '{}+{}j'.format(real, imag)
+    return real


Test patch:
diff --git a/test/python/visualization/test_circuit_text_drawer.py b/test/python/visualization/test_circuit_text_drawer.py
--- a/test/python/visualization/test_circuit_text_drawer.py
+++ b/test/python/visualization/test_circuit_text_drawer.py
@@ -1475,6 +1475,10 @@ def test_text_empty_circuit(self):
         circuit = QuantumCircuit()
         self.assertEqual(str(_text_circuit_drawer(circuit, idle_wires=False)), expected)
 
+
+class TestTextNonRational(QiskitTestCase):
+    """ non-rational numbers are correctly represented """
+
     def test_text_pifrac(self):
         """ u2 drawing with -5pi/8 fraction"""
         expected = '\n'.join(["        ┌───────────────┐",
@@ -1486,6 +1490,48 @@ def test_text_pifrac(self):
         circuit.u2(pi, -5 * pi / 8, qr[0])
         self.assertEqual(str(_text_circuit_drawer(circuit)), expected)
 
+    def test_text_complex(self):
+        """Complex numbers show up in the text
+        See https://github.com/Qiskit/qiskit-terra/issues/3640 """
+        expected = '\n'.join(["        ┌────────────────────────────────────┐",
+                              "q_0: |0>┤0                                   ├",
+                              "        │  initialize(0.5+0.1j,0,0,0.86023j) │",
+                              "q_1: |0>┤1                                   ├",
+                              "        └────────────────────────────────────┘"
+                              ])
+        ket = numpy.array([0.5 + 0.1 * 1j, 0, 0, 0.8602325267042626 * 1j])
+        circuit = QuantumCircuit(2)
+        circuit.initialize(ket, [0, 1])
+        self.assertEqual(circuit.draw(output='text').single_string(), expected)
+
+    def test_text_complex_pireal(self):
+        """Complex numbers including pi show up in the text
+        See https://github.com/Qiskit/qiskit-terra/issues/3640 """
+        expected = '\n'.join(["        ┌─────────────────────────────────┐",
+                              "q_0: |0>┤0                                ├",
+                              "        │  initialize(pi/10,0,0,0.94937j) │",
+                              "q_1: |0>┤1                                ├",
+                              "        └─────────────────────────────────┘"
+                              ])
+        ket = numpy.array([0.1*numpy.pi, 0, 0, 0.9493702944526474*1j])
+        circuit = QuantumCircuit(2)
+        circuit.initialize(ket, [0, 1])
+        self.assertEqual(circuit.draw(output='text').single_string(), expected)
+
+    def test_text_complex_piimaginary(self):
+        """Complex numbers including pi show up in the text
+        See https://github.com/Qiskit/qiskit-terra/issues/3640 """
+        expected = '\n'.join(["        ┌─────────────────────────────────┐",
+                              "q_0: |0>┤0                                ├",
+                              "        │  initialize(0.94937,0,0,pi/10j) │",
+                              "q_1: |0>┤1                                ├",
+                              "        └─────────────────────────────────┘"
+                              ])
+        ket = numpy.array([0.9493702944526474, 0, 0, 0.1*numpy.pi*1j])
+        circuit = QuantumCircuit(2)
+        circuit.initialize(ket, [0, 1])
+        self.assertEqual(circuit.draw(output='text').single_string(), expected)
+
 
 class TestTextInstructionWithBothWires(QiskitTestCase):
     """Composite instructions with both kind of wires