Repository: Qiskit/qiskit

Issue:
Pulse and Schedule plots do not start at t0=0
<!-- ⚠️ 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?
As noted in https://github.com/Qiskit/qiskit-terra/pull/3418#pullrequestreview-313349295, the pulse and schedule plots do not start at t=0, nor do they finish at `t=t0+duration`


### Steps to reproduce the problem
```python
import qiskit.pulse as pulse
import qiskit.pulse.pulse_lib as pulse_lib
sched = pulse.Schedule()
sched += pulse_lib.constant(10, 1.0)(pulse.DriveChannel(1))
sched.draw(channels_to_plot=[pulse.DriveChannel(1)])
```


### What is the expected behavior?
They should start and stop at t0(duration)


### Suggested solutions
Any ideas @nkanazawa1989?




Discussion:
I looked through the code a little more and it looks like it may be happening within the `_draw_channels` function. I tried playing around with the code in there, and if I have set the `time` array's first entry to 0, then the channel's figure correctly starts at 0. (Currently, `time`'s first entry is 0.5, which is the amount of offset we see). I have not been able to reproduce the same fix for the end of the channel's figure though. Will play around with it a little more.
@taalexander I think it is a problem of how to interpolate discrete pulse. As I remember, time shift of +0.5 indicates sampling at midpoint. i.e.
```
sample = [s0, s1, s2]
time = [t0, t1, t2, t3]
```
It should be noted that if you have sample pulse of duration 3, a length of time vector becomes 4 because it should start from 0, or t0. When visualizer interpolates this envelope, it resamples the above vectors to be  [(t0+t1)/2, s0], [(t1+t2)/2, s1], [(t2+t3)/2, s2] - this is why your square pulse starts from 0.5, and ends at tf - 0.5.

If you remove the time shift, visualizer returns the figure exactly the same as _left_ sampling strategy and pulse ends at t2 in above example. This is confusing because pulse of duration 3 ends at t2.
I don't think we should be interpolating by default (after all our pulses *are* discrete waveforms). What we should be plotting is [t0, t1, t1, t2, t2, t3] and [s0, s0, s1, s1, s2, s2]. If we want to interpolate on that, it would be fine.
Not because I have a sure fix but just to learn, may I come through and poke around until I find something. Good starting pointers welcome. 
@taalexander agreed. but `cubic` interpolation raises an error with that vectors, `ValueError: Expect x to be a 1-D sorted array_like.`
@faraimazh feel free to poke around and comment here if you have any questions!
@nkanazawa1989 would either of the two solution work?
1. Use a switch statement to use the vectors above I mention if interpolation is off (which I think it should be by default).
2. Modify the vectors to be [t0, t1-epsilon, t1+epsilon, t2-epsilon, t2+epsilon, t3] and [s0, s0, s1, s1, s2, s2]
1 looks easy. In default, visualizer uses linear interpolation instead of disabling.
Ok, than. Option one it is :smile:!
@faraimazh do you still plan to work on this?
Sure, no problem. If I make progress I will let you know.

On Wed., 8 Jan. 2020, 01:23 Thomas Alexander, <notifications@github.com>
wrote:

> @faraimazh <https://github.com/faraimazh> do you still plan to work on
> this? Otherwise, I will reassign.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/Qiskit/qiskit-terra/issues/3427?email_source=notifications&email_token=AIPNQSRZUQLG54SPKVL575TQ4UFHFA5CNFSM4JKHK5DKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIKUQ3Q#issuecomment-571820142>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AIPNQSUZQ7NXKCDZ7376PCLQ4UFHFANCNFSM4JKHK5DA>
> .
>

Hi @faraimazh, how is this going?
@lcapelluto thanks for checking. I am only starting to follow now. I had to read a bit on terra and OpenPulse. I am not there yet but ready to get my hands dirty. Excuse my noob-ness, where do I find the drawing function or visualization files?
the files are here.
https://github.com/Qiskit/qiskit-terra/tree/master/qiskit/visualization/pulse

and interpolation code is here.
https://github.com/Qiskit/qiskit-terra/blob/ff6b94120520b5c27d6316088eafc90338a97914/qiskit/visualization/pulse/interpolation.py#L26-L49

good luck and I'm happy to help :)
> the files are here.
> https://github.com/Qiskit/qiskit-terra/tree/master/qiskit/visualization/pulse
> 
> and interpolation code is here.
> https://github.com/Qiskit/qiskit-terra/blob/ff6b94120520b5c27d6316088eafc90338a97914/qiskit/visualization/pulse/interpolation.py#L26-L49
> 
> good luck and I'm happy to help :)

Thanks. I am on it.
After setting up my environment and all, when I run the code to reproduce the problem here is the error I get.
![2020-02-04 (2)](https://user-images.githubusercontent.com/35575882/73813107-adf8c280-47e7-11ea-84c5-70dd6131b990.png)
![2020-02-04](https://user-images.githubusercontent.com/35575882/73813108-ae915900-47e7-11ea-8181-7050289ba166.png)
![2020-02-04 (1)](https://user-images.githubusercontent.com/35575882/73813109-af29ef80-47e7-11ea-86f9-878ff521fb05.png)



> After setting up my environment and all, when I run the code to reproduce the problem here is the error I get.
> ![2020-02-04 (2)](https://user-images.githubusercontent.com/35575882/73813107-adf8c280-47e7-11ea-84c5-70dd6131b990.png)
> ![2020-02-04](https://user-images.githubusercontent.com/35575882/73813108-ae915900-47e7-11ea-8181-7050289ba166.png)
> ![2020-02-04 (1)](https://user-images.githubusercontent.com/35575882/73813109-af29ef80-47e7-11ea-86f9-878ff521fb05.png)

Issue resolved. I had two folders for qiskit-terra and in one of them there was a corrupt file. 

Resolving patch:
diff --git a/qiskit/visualization/pulse/interpolation.py b/qiskit/visualization/pulse/interpolation.py
--- a/qiskit/visualization/pulse/interpolation.py
+++ b/qiskit/visualization/pulse/interpolation.py
@@ -45,14 +45,36 @@ def interp1d(time: np.ndarray,
     dt = time[1] - time[0]
 
     time += 0.5 * dt
-    cs_ry = interpolate.interp1d(time[:-1], re_y, kind=kind, bounds_error=False)
-    cs_iy = interpolate.interp1d(time[:-1], im_y, kind=kind, bounds_error=False)
+    cs_ry = interpolate.interp1d(
+        time[:-1], re_y, kind=kind, bounds_error=False)
+    cs_iy = interpolate.interp1d(
+        time[:-1], im_y, kind=kind, bounds_error=False)
 
     time_ = np.linspace(time[0], time[-1] * dt, nop)
 
     return time_, cs_ry(time_), cs_iy(time_)
 
 
+def step_wise(time: np.ndarray,
+              samples: np.ndarray,
+              nop: int
+              ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
+    # pylint: disable=unused-argument
+    """Keep uniform variation between sample values. No interpolation is applied.
+    Args:
+        time: Time vector with length of ``samples`` + 1.
+        samples: Complex pulse envelope.
+        nop: This argument is not used.
+    Returns:
+        Time vector and real and imaginary part of waveform.
+    """
+    samples_ = np.repeat(samples, 2)
+    re_y_ = np.real(samples_)
+    im_y_ = np.imag(samples_)
+    time__ = np.concatenate(([time[0]], np.repeat(time[1:-1], 2), [time[-1]]))
+    return time__, re_y_, im_y_
+
+
 linear = partial(interp1d, kind='linear')
 linear.__doc__ = """Apply linear interpolation between sampling points.
 
@@ -74,14 +96,3 @@ def interp1d(time: np.ndarray,
 Returns:
     Interpolated time vector and real and imaginary part of waveform.
 """
-
-step_wise = partial(interp1d, kind='nearest')
-step_wise.__doc__ = """No interpolation.
-
-Args:
-    time: Time vector with length of ``samples`` + 1.
-    samples: Complex pulse envelope.
-    nop: Number of data points for interpolation.
-Returns:
-    Interpolated time vector and real and imaginary part of waveform.
-"""


Test patch: