Repository: Qiskit/qiskit

Issue:
Custom multiqubit gates overlap
<!-- ⚠️ 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**: master

### What is the current behavior?
Custom multiqubit gates can overlap other gates. 
![image](https://user-images.githubusercontent.com/40489777/64109983-c6683b00-cd78-11e9-9bcd-a3e5e11f0f35.png)
I think this is because the width of a layer has to be an integer, and this is what happens when the layer is given a width of 2. The result for a width of 3 below is obviously still not desirable but at least there is not overlap.
![image](https://user-images.githubusercontent.com/40489777/64110058-fa436080-cd78-11e9-9a58-774413a6d931.png)

### Steps to reproduce the problem
```python
q = QuantumRegister(3)
c = ClassicalRegister(3)
circ1 = QuantumCircuit(q, c, name='my instruction')
circ1.measure(1, 1)
inst = circ1.to_instruction()

circ2 = QuantumCircuit(q, c, name='circ2')
circ2.h(0)
circ2.append(inst, q[:], c[:])
circ2.draw(output='mpl')
```
### What is the expected behavior?
The custom gate is drawn a suitable distance away from the previous gate


### Suggested solutions
Look at how to modify where the gate is plotted, maybe by taking more into consideration in `Anchor.plot_coord()`




Discussion:
Would it be possible to adjust the way in which the `layer_width` is calculated? I looked into the `_draw_ops()` function, specifically the part that gets executed when drawing a custom gate with a name longer than 4 chars.

The way it currently is now, I see a few possible scenarios:
1) `box_width <= 1`, which causes `box_width` to be set to 2 and `layer_width` to be set to 2 
2) `box_width == 2`, which causes `layer_width` to be set to 2
3) `box_width > 2` which causes `layer_width` to be set to `box_width * 2`

The problem lies in scenario 2, where `box_width` and `layer_width` are the same causing the overlap. The overlap does not happen for larger `box_width`s, but the spacing between the custom gate and the adjacent gates can get pretty large depending on the box_width.

My suggestion was to replace this block of code:
```
if box_width <= 1:
    box_width = 2
    if layer_width < box_width:
        if box_width > 2:
            layer_width = box_width * 2
        else:
            layer_width = 2
```
with this:
```
layer_width = math.ceil(box_width * 1.5)
```

I've tested drawing the circuit with this code and the gates seem to be fairly close together without any gate overlap. There is some text overlap, but I currently see that without my changes as well. From what I can see, the code being replaced by this should not affect anything else, but if you see anything I might have missed, please let me know.

Here are some examples of the `circuit.draw(output='mpl')` with this change:
`box_width == 1`
<img width="286" alt="Screen Shot 2019-09-10 at 4 21 39 PM" src="https://user-images.githubusercontent.com/50181769/64647753-98719f00-d3e7-11e9-8d8f-13c141ee10f7.png">

`box_width == 2`
<img width="352" alt="Screen Shot 2019-09-10 at 4 23 36 PM" src="https://user-images.githubusercontent.com/50181769/64647754-98719f00-d3e7-11e9-94fb-07df0464e4bd.png">

`box_width == 3`
<img width="440" alt="Screen Shot 2019-09-10 at 4 23 49 PM" src="https://user-images.githubusercontent.com/50181769/64647755-98719f00-d3e7-11e9-93a2-695152e82f0e.png">

`box_width == 4`
<img width="481" alt="Screen Shot 2019-09-10 at 4 24 02 PM" src="https://user-images.githubusercontent.com/50181769/64647756-98719f00-d3e7-11e9-94dc-12c3a0347d02.png">

@Matt-Stypulkoski This looks like a good start! Are you able to fix the text overlap too? As this will mean that the boxes need to be slightly bigger to allow for it. Maybe this could be done by adjusting your factor `1.5`
I've been working on trying to fix the text overlap. For the most part I know what I need to adjust and have been able to get it to stop the overlap for the most part. It just depends on how much space we are willing to have left over in the gate's rectangle. 

The longer the text, the more space is generated on the sides. This sometimes causes some issues, as you can have a long string of text that doesn't take up much space, as well as a shorter string of text that takes up a larger amount of space (W's and numbers are larger). I'll attach some images of different length text. I can adjust things if it looks like there is too much space. I tried to focus on the smaller gates looking cleaner, as I felt a user would be more likely to have their gate name text be smaller rather than larger

<img width="385" alt="Screen Shot 2019-09-12 at 4 02 07 PM" src="https://user-images.githubusercontent.com/50181769/64816973-c802e180-d576-11e9-8b7f-7bd07e504bf1.png">
<img width="385" alt="Screen Shot 2019-09-12 at 4 02 22 PM" src="https://user-images.githubusercontent.com/50181769/64816975-c802e180-d576-11e9-99b1-105e1079c72c.png">
<img width="424" alt="Screen Shot 2019-09-12 at 4 02 31 PM" src="https://user-images.githubusercontent.com/50181769/64816977-c802e180-d576-11e9-80c9-389a016e5df1.png">
<img width="609" alt="Screen Shot 2019-09-12 at 4 02 40 PM" src="https://user-images.githubusercontent.com/50181769/64816978-c802e180-d576-11e9-9b39-0dcc525797ef.png">


These really display how much larger some letters/numbers compared to others
Numbers have a little less space than the "small" gate above, and can blend in with the numbers representing input qubits on the left side
<img width="324" alt="Screen Shot 2019-09-12 at 4 05 03 PM" src="https://user-images.githubusercontent.com/50181769/64817211-58412680-d577-11e9-8d46-085d47f46034.png">

Capital letters can be troublesome. This string of W's has the same amount of characters as the "small" gate above, but has overlap.
<img width="324" alt="Screen Shot 2019-09-12 at 4 07 10 PM" src="https://user-images.githubusercontent.com/50181769/64817241-6727d900-d577-11e9-96c2-e9750b54135d.png">


@maddy-tod I have been digging a little more into this issue, but cannot seem to improve on what I had in my previous post.  It seems to work well for smaller and slightly larger gate names, but for much larger ones the margin tends to be more than what might be needed. The string of W's example also has overlap, but could not replicate that with many other short string of capital letters.

Do you have any suggestions? Or do you think these flaws are not that impactful?

Resolving patch:
diff --git a/qiskit/visualization/matplotlib.py b/qiskit/visualization/matplotlib.py
--- a/qiskit/visualization/matplotlib.py
+++ b/qiskit/visualization/matplotlib.py
@@ -189,10 +189,10 @@ def _custom_multiqubit_gate(self, xy, cxy=None, fc=None, wide=True, text=None,
             ypos = min([y[1] for y in cxy])
         if wide:
             if subtext:
-                boxes_length = round(max([len(text), len(subtext)]) / 8) or 1
+                boxes_length = round(max([len(text), len(subtext)]) / 6) or 1
             else:
-                boxes_length = round(len(text) / 8) or 1
-            wid = WID * 2.2 * boxes_length
+                boxes_length = math.ceil(len(text) / 6) or 1
+            wid = WID * 2.5 * boxes_length
         else:
             wid = WID
 
@@ -224,6 +224,7 @@ def _custom_multiqubit_gate(self, xy, cxy=None, fc=None, wide=True, text=None,
                          clip_on=True, zorder=PORDER_TEXT)
 
         if text:
+
             disp_text = text
             if subtext:
                 self.ax.text(xpos, ypos + 0.5 * height, disp_text, ha='center',
@@ -241,7 +242,8 @@ def _custom_multiqubit_gate(self, xy, cxy=None, fc=None, wide=True, text=None,
                              fontsize=self._style.fs,
                              color=self._style.gt,
                              clip_on=True,
-                             zorder=PORDER_TEXT)
+                             zorder=PORDER_TEXT,
+                             wrap=True)
 
     def _gate(self, xy, fc=None, wide=False, text=None, subtext=None):
         xpos, ypos = xy
@@ -668,7 +670,8 @@ def _draw_ops(self, verbose=False):
                 elif op.name not in ['barrier', 'snapshot', 'load', 'save',
                                      'noise', 'cswap', 'swap', 'measure'] and len(
                                          op.name) >= 4:
-                    box_width = round(len(op.name) / 8)
+                    box_width = math.ceil(len(op.name) / 6)
+
                     # handle params/subtext longer than op names
                     if op.type == 'op' and hasattr(op.op, 'params'):
                         param = self.param_parse(op.op.params)
@@ -684,13 +687,7 @@ def _draw_ops(self, verbose=False):
                                     layer_width = 2
                             continue
                     # If more than 4 characters min width is 2
-                    if box_width <= 1:
-                        box_width = 2
-                    if layer_width < box_width:
-                        if box_width > 2:
-                            layer_width = box_width * 2
-                        else:
-                            layer_width = 2
+                    layer_width = math.ceil(box_width * WID * 2.5)
 
             this_anc = prev_anc + 1
 


Test patch: