Skip to content
Advertisement

fill between vertical curves in the sub plot

Dears, I have the following csv file

depth lst dol Anhd sst
50 20 40 80 100
100 25 50 85 100
150 15 35 75 100

I take the data from csv to draw subplot contains four curves in the same subplot, I have filled by red color from left edge to first curve, also I have filled by blue color from last curve to right edge, I want to fill between entire curves in between first and last curve and make color legend. the table is equal to csv file

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import pandas as pd
import re
import json
test = r'D:pythonTEST-COMPOSITION.csv'
test =pd.read_csv(test)
mineral_names = test.drop(['depth'],axis=1)
mineral_names = list(mineral_names.columns.values)
colors = ["green", "gray"]
fig = plt.figure(figsize=(15, 12), dpi=100, tight_layout=True)
gs = gridspec.GridSpec(nrows=1, ncols=10, wspace=0)
fig.add_subplot(gs[0, 1])
for i in range(len(mineral_names)-1):

   plt.plot(test[mineral_names[i]],test['depth'],linewidth=2, color='black')
for i in range(len(mineral_names)-1):
    if i == 0:
      left_col_value = 0
      right_col_value = 100
      span = abs(left_col_value - right_col_value)
      cmap = plt.get_cmap('hot_r')
      color_index = np.arange(left_col_value, right_col_value, span / 100)
      for index in sorted(color_index):
        index_value = (index - left_col_value) / span
        plt.fill_betweenx(test['depth'],test[mineral_names[0]], left_col_value, where=test[mineral_names[i]] >= index, color="red")
    if i ==  range(len(mineral_names)-1)[-1]:
      left_col_value = 0
      right_col_value = 100
      span = abs(left_col_value - right_col_value)
      cmap = plt.get_cmap('hot_r')
      color_index = np.arange(left_col_value, right_col_value, span / 100)
      for index in sorted(color_index):
        index_value = (index - left_col_value) / span
        plt.fill_betweenx(test['depth'],test[mineral_names[i]], right_col_value, where=test[mineral_names[i]] >= index, color="blue")

    #if i ==1:
        #plt.fill_betweenx(test['depth'], test[mineral_names[i+1]], test[mineral_names[i]],color = "green", alpha=0.4)



plt.gca().invert_yaxis()
plt.show()```

Advertisement

Answer

Here is an approach looping through the curves, and using a variable previous_curve which contains the position of the previous curve. At the start, the previous curve is all zeros. Similarly, the name of the previous curve can be saved and used as a label for the fill. All labels will appear in the default legend.

The example code below uses a gridspec with only 4 columns, to make the example plot a bit clearer.

import matplotlib.pyplot as plt
from matplotlib import gridspec
import pandas as pd
import numpy as np

test = pd.DataFrame({'depth': [50, 100, 150],
                     'lst': [20, 25, 15],
                     'dol': [40, 50, 35],
                     'Anhd': [80, 85, 75],
                     'sst': [100, 100, 100]})
mineral_names = test.columns[1:]
fig = plt.figure(figsize=(15, 12), dpi=100, tight_layout=True)
gs = gridspec.GridSpec(nrows=1, ncols=4, wspace=0)

ax = fig.add_subplot(gs[0, 1])
for mineral_name in mineral_names[:-1]:
    ax.plot(test[mineral_name], test['depth'], linewidth=2, color='black')

colors = ["red", "green", "gray", "blue"]
previous_curve = 0
previous_name = ''
for mineral_name, color in zip(mineral_names, colors):
    ax.fill_betweenx(test['depth'], previous_curve, test[mineral_name], color=color, alpha=0.4,
                     label=f'{previous_name} - {mineral_name}')
    previous_curve = test[mineral_name]
    previous_name = mineral_name
ax.margins(x=0, y=0)  # no white space in plot
ax.invert_yaxis()
ax.legend()
plt.show()

using fill_between_x for multiple curves

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement