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()