4

I'm trying to rotate correctly the matplotlib step plot. First I swapped the x and y axes and reversed the y axis. I made the step plot again. However, the direction of the step line (blue color) was not as desired in the right picture and the red colored stepping line is the superimposed rotated image of the left picture. Here is my code

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(14)
y = np.sin(x / 2)

fig, (ax, bx) = plt.subplots(nrows=1, ncols=2, figsize=(11.5, 5.5))
fig.subplots_adjust(left=0.08, bottom=0.13, top=0.98, right=0.97, wspace=0.2, hspace=0.0)

ax.step(x, y, where='mid', c='r')
ax.plot(x, y, 'o--', color='grey', alpha=0.3)

bx.invert_yaxis()
bx.step(y, x, where='pre', c='b')
bx.plot(y, x, 'o--', color='grey', alpha=0.3)

plt.show()

I am trying to make red colored step plot as shown in the right picture. How can I do this?

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80
Bluerose
  • 131
  • 1
  • 13

2 Answers2

3

The desired step-style can be obtained by shifting a little bit the second coordinates and using where=pre.

def plot_step_invert_mid(x, y, *args, **kwargs):
    y_new = np.insert(y, 0, y[0])
    y_new = 0.5 * (y_new[1:] + y_new[:-1])
    x_new = np.append(x, x[-1])
    y_new = np.append(y_new, y[-1])
    plt.step(x_new, y_new, where="pre", *args, **kwargs)

fig, (ax, bx) = plt.subplots(nrows=1, ncols=2, figsize=(11.5, 5.5))
fig.subplots_adjust(left=0.08, bottom=0.13, top=0.98, right=0.97, wspace=0.2, hspace=0.0)

ax.step(x, y, where="mid", c='r')
ax.plot(x, y, 'o--', color='grey', alpha=0.3)

bx.invert_yaxis()
plot_step_invert_mid(y, x)
bx.plot(y, x, 'o--', color='grey', alpha=0.3)

results

nonin
  • 704
  • 4
  • 10
  • 1
    Nice answer, I think it's good to leave the data unscathed. – Matt Hall Aug 06 '21 at 18:51
  • 2
    A small drawback lies in the fact that `plot_step_invert_mid(y, x, "ro-")` will not display the markers in the desired location. – nonin Aug 06 '21 at 18:55
  • Ah, right, I see what you mean... it's a tricky problem. Of course you can always plot the data itself. This would make a nice enhancement to matplotlib. – Matt Hall Aug 06 '21 at 19:05
  • 1
    It is good answer without using external package. Thank you very much for defining a subroutine. – Bluerose Aug 07 '21 at 15:27
  • Thanks again @noin, What changes should be made for 'pre' and 'post' options of the step plot? – Bluerose Aug 07 '21 at 15:41
  • Basically switch both options! An inverted "pre" is a "post", and vice versa. – nonin Aug 07 '21 at 15:46
0

I suggest you to interpolate your original curve with scipy.interpolate.interp1d rather then use the matplotlib.pyplot.step method of plotting. This because interp1d generates a new vector that you can manipulate as you wish.
In the code below:

  1. x and y are the original curve vectors (length 14)
  2. xx and yy are the original curve interpolated vectors (length N)

In order to rotate the plot you can simply swap x with y and xx with yy in plt.plot:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

x = np.arange(14)
y = np.sin(x/2)

N = 1000
xx = np.linspace(0, 13, N)
yy = interp1d(x, y, kind = 'nearest')(xx)

fig, (ax, bx) = plt.subplots(nrows = 1, ncols = 2, figsize = (11.5, 5.5))
fig.subplots_adjust(left = 0.08, bottom = 0.13, top = 0.98, right = 0.97, wspace = 0.2, hspace = 0.0)

ax.plot(xx, yy, 'r')
ax.plot(x, y, 'o--', color = 'grey', alpha = 0.3)

bx.invert_yaxis()
bx.plot(yy, xx, 'r')
bx.plot(y, x, 'o--', color = 'grey', alpha = 0.3)

plt.show()

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80
  • I find the original version of this answer more interesting because it generalized the problem to any angle. – nonin Aug 06 '21 at 19:00
  • Thank you, I think you are right, but in the original version the y axis wasn't reversed, so the answer didn't solve the specific issue of the questioner; I noticed it only later – Zephyr Aug 06 '21 at 19:04
  • This is quite an interesting solution,, but using a external subroutine is not desired, at least for me. – Bluerose Aug 07 '21 at 15:30