Reputation: 702
I have a dataframe with three features: DEPTH, PERMEABILITY and POROSITY. And I would like to plot DEPTH at y axis and PERMEABILITY and POROSITY together at x axis, although these last two features have different scales.
df = pd.DataFrame({'DEPTH(m)': [100, 150, 200, 250, 300, 350, 400, 450, 500, 550],
'PERMEABILITY(mD)': [1000, 800, 900, 600, 200, 250, 400, 300, 100, 200],
'POROSITY(%)': [0.30, 0.25, 0.15, 0.19, 0.15, 0.10, 0.15, 0.19, 0.10, 0.15]})
I already managed to plot them together, but now I need to fill with two different colors the areas between the curves. For example, when PERMEABILITY curve is on the right side of POROSITY, the area between them should be green. If PERMEABILITY is on the left side, the area between curves should be yellow.
f, ax1 = plt.subplots()
ax1.set_xlabel('PERMEABILITY(mD)')
ax1.set_ylabel('DEPTH(m)')
ax1.set_ylim(df['DEPTH(m)'].max(), df['DEPTH(m)'].min())
ax1.plot(df['PERMEABILITY(mD)'], df['DEPTH(m)'], color='red')
ax1.tick_params(axis='x', labelcolor='red')
ax2 = ax1.twiny()
ax2.set_xlabel('POROSITY(%)')
ax2.plot(df['POROSITY(%)'], df['DEPTH(m)'], color='blue')
ax2.tick_params(axis='x', labelcolor='blue')
So the right output should be like this: (Sorry for the Paint image below)
Anyone could help me with this?
Upvotes: 1
Views: 294
Reputation: 2741
You can use the fill_betweenx()
function, however you need to convert one of your axis to the scale of the other one, because you use twiny
. Below, I converted your POROSITY data to fit to the axis of PERMEABILITY.
Then you can use two conditional fill_betweenx
, where the two curves are larger than each other, to assign different colors to those patches. Also, since your data is discrete, you need to set interpolate=True
in your fill_betweenx
functions.
f, ax1 = plt.subplots()
ax1.set_xlabel('PERMEABILITY(mD)')
ax1.set_ylabel('DEPTH(m)')
ax1.set_ylim(df['DEPTH(m)'].max(), df['DEPTH(m)'].min())
ax1.plot(df['PERMEABILITY(mD)'], df['DEPTH(m)'], color='red')
ax1.tick_params(axis='x', labelcolor='red')
ax2 = ax1.twiny()
ax2.set_xlabel('POROSITY(%)')
ax2.plot(df['POROSITY(%)'], df['DEPTH(m)'], color='blue')
ax2.tick_params(axis='x', labelcolor='blue')
# convert POROSITY axis to PERMEABILITY
# value-min / range -> normalized POROSITY (normp)
# normp*newrange + newmin -> stretched POROSITY to PERMEABILITY
z=df['POROSITY(%)']
x=df['PERMEABILITY(mD)']
nz=((z-np.min(z))/(np.max(z)-np.min(z)))*(np.max(x)-np.min(x))+np.min(x)
# fill between in green where PERMEABILITY is larger
ax1.fill_betweenx(df['DEPTH(m)'],x,nz,where=x>=nz,interpolate=True,color='g')
# fill between in yellow where POROSITY is larger
ax1.fill_betweenx(df['DEPTH(m)'],x,nz,where=x<=nz,interpolate=True,color='y')
plt.show()
The result is as below (I might have used different colors, but I assume that's not a concern).
Upvotes: 5