I am trying to fill the area between the curve and x=0 with Matplotlib fill_between()
method. For some reason, the shading appears to be shifted to the left, as can be seen from the picture. I should mention that this is one of 3 subplots I plot next to each other horizontally.
This is the code I use
import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 300
from matplotlib import pyplot as plt
fig, axs = plt.subplots(1, 3)
fig.tight_layout()
ticks_x1 = [-400,1200,4]
major_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],ticks_x1[2] 1)
minor_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],5*ticks_x1[2] 1)
axs[1].plot(V, -z, 'tab:cyan', linewidth=2, solid_capstyle='round')
axs[1].set_title('Querkraft')
axs[1].set(xlabel='V [kN]')
axs[1].set_xticks(major_ticks_x1)
axs[1].set_xticks(minor_ticks_x1,minor=True);
axs[1].fill_between(
x= V,
y1= -z,
color= "cyan",
alpha= 0.2)
How could I fix that? Thank you.
CodePudding user response:
I believe it's because the start of your function is not zero (I think that would be V[0] in your case).
Here's how I can reproduce your problem and (sort of) fix it (using a simple function):
import matplotlib as mpl
import numpy as np
from matplotlib import pyplot as plt
mpl.rcParams['figure.dpi'] = 300
fig, axs = plt.subplots(1, 3)
fig.tight_layout()
ticks_x1 = [-400,1200,4]
major_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],ticks_x1[2] 1)
minor_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],5*ticks_x1[2] 1)
# V[0] will not be zero
z = np.linspace(-3,3, 1000)
V= np.sin(z)
axs[0].plot(V, -z, 'tab:cyan', linewidth=2, solid_capstyle='round')
axs[0].set_title('Querkraft')
axs[0].set(xlabel='V [kN]')
axs[0].set_xticks(major_ticks_x1)
axs[0].set_xticks(minor_ticks_x1,minor=True);
axs[0].grid()
axs[0].fill_between(
x= V,
y1= -z,
color= "cyan",
alpha= 0.2)
print(V[0])
Okay - that creates the graph with the "offset" fill_between (see below)
Now construct V so that V[0] will be zero
z = np.linspace(-np.pi,np.pi, 1000)
V= np.sin(z)
axs[1].plot(V, -z, 'tab:cyan', linewidth=2, solid_capstyle='round')
axs[0].set_title('Querkraft'.format(V.min()))
axs[1].set(xlabel='V [kN]')
axs[1].set_xticks(major_ticks_x1)
axs[1].set_xticks(minor_ticks_x1,minor=True);
axs[1].grid()
axs[1].fill_between(
x= V,
y1= -z,
color= "cyan",
alpha= 0.2)
This is what those two graphs look like:
I believe the reason for this is that fill_between is intended for horizontal fill_between, where you're filling between two y values - often the x axis is implicitly the origin of the fill_between.
When you work horizontally, the x in your curve is more obviously defining where the fill between should start and stop. When you use fill_between vertically like this, it is not quite as obvious.
Here's a more typical (horizontal) use of fill_between, that makes it more clear that the beginning and end of the curve are defining where to start and stop the fill:
Now of course, I only 'sort of' fixed your problem, because I changed the range of my function so that V[0] was zero - you might be constrained from doing that. But you can at least see why the fill_between was acting as it was.
CodePudding user response:
Ok, I think I have found a solution. Matplotlib has a method fill_betweenx()
.
Now the code looks like this
import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 300
from matplotlib import pyplot as plt
fig, axs = plt.subplots(1, 3)
fig.tight_layout()
ticks_x1 = [-400,1200,4]
major_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],ticks_x1[2] 1)
minor_ticks_x1 = np.linspace(ticks_x1[0],ticks_x1[1],5*ticks_x1[2] 1)
axs[1].plot(V, -z, 'tab:cyan', linewidth=2, solid_capstyle='round')
axs[1].set_title('Querkraft')
axs[1].set(xlabel='V [kN]')
axs[1].set_xticks(major_ticks_x1)
axs[1].set_xticks(minor_ticks_x1,minor=True);
axs[1].fill_betweenx(
y= -z,
x1= V,
color= "cyan",
alpha= 0.2)
and produces the desired result. I guess it did not work with the firs method because the graph is vertical instead of horizontal.