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