Home > Blockchain >  Python Matplotlib fill from fill_between() method shifted
Python Matplotlib fill from fill_between() method shifted

Time:09-30

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)


enter image description here

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: enter image description here

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:

enter image description here

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.

enter image description here

  • Related