matplotlib 最小值的填充颜色位于前面

6yt4nkrj  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(111)

我有光谱数据,想一起比较多个图。出于可视化目的,我想填充图下方的区域,最小的图始终位于前面。这是图中未填充的一小部分区域。

在第一个峰中,从最小到最大依次为A、B、C、D、E。第二个峰则相反:E、D、C、B、A。在绘图的其他地方,顺序可能会改变,并且可能是非连续的(A、D、C、E、B)。
以下是我希望最终结果的外观:

我一直在使用fill_between,但在峰值强度发生变化时遇到了问题。
下面是用于测试的df部分:

A      B      C       D       E
spectra                                     
1.60       628    807    829     973     966
1.62      1173   1420   1620    1793    1968
1.64      3567   4512   4887    5783    6232
1.66     10365  13056  14254   17340   18286
1.68     23984  30503  33717   40242   43373
1.70     42923  54741  60679   72537   78680
1.72     59167  75363  83009   99574  107083
1.74     62070  78808  87334  104371  112352
1.76     49772  63391  69182   84503   90189
1.78     31434  39861  43771   52512   56310
1.80     16219  20637  22614   26787   28825
1.82      7632   9828  10545   12298   13602
1.84      4094   4920   5197    6192    6647
1.86      2398   2738   2851    3411    3593
1.88      1433   1508   1598    1781    1804
1.90       918    895    870     858     903
1.92       693    600    595     564     546
1.94       702    622    529     468     430
1.96       637    600    507     430     396
1.98       580    535    511     461     437
2.00       530    534    482     416     449
2.02       568    453    464     387     404
2.04       421    365    353     317     318
2.06       357    327    290     263     235
2.08       344    292    245     226     188
2.10       320    269    200     182     153
2.12       321    263    235     185     162
2.14       407    304    279     197     145
2.16       681    527    429     274     191
2.18      1537   1140    920     580     382
2.20      3962   2789   2288    1321     768
2.22      9686   6951   5331    3050    1765
2.24     21056  15007  11416    6436    3752
2.26     38267  26874  20562   11561    6637
2.28     55706  39067  29799   16900    9596
2.30     64310  45348  34907   19514   11307
2.32     59707  42021  31802   18299   10180
2.34     44050  31169  23458   13561    7769
2.36     25907  18337  13965    7889    4576
2.38     13059   9341   6997    3978    2401
2.40      6294   4539   3472    1966    1296
2.42      4272   3028   2389    1391     892
2.44      3995   2956   2312    1344     862
2.46      3970   2898   2267    1351     862
2.48      3496   2522   2055    1153     731
2.50      2512   1815   1512     938     613
x4shl7ld

x4shl7ld1#

下面的方法使用fill_between表示每对连续的x值,并对y值进行排序。显然,连续的fill_between有时会留下一些小间隙。为了解决这个问题,代码一次性绘制了具有相同顺序的所有块。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from io import StringIO

data_str = '''spectra             A      B      C       D       E                            
1.60       628    807    829     973     966
1.62      1173   1420   1620    1793    1968
1.64      3567   4512   4887    5783    6232
1.66     10365  13056  14254   17340   18286
1.68     23984  30503  33717   40242   43373
1.70     42923  54741  60679   72537   78680
1.72     59167  75363  83009   99574  107083
1.74     62070  78808  87334  104371  112352
1.76     49772  63391  69182   84503   90189
1.78     31434  39861  43771   52512   56310
1.80     16219  20637  22614   26787   28825
1.82      7632   9828  10545   12298   13602
1.84      4094   4920   5197    6192    6647
1.86      2398   2738   2851    3411    3593
1.88      1433   1508   1598    1781    1804
1.90       918    895    870     858     903
1.92       693    600    595     564     546
1.94       702    622    529     468     430
1.96       637    600    507     430     396
1.98       580    535    511     461     437
2.00       530    534    482     416     449
2.02       568    453    464     387     404
2.04       421    365    353     317     318
2.06       357    327    290     263     235
2.08       344    292    245     226     188
2.10       320    269    200     182     153
2.12       321    263    235     185     162
2.14       407    304    279     197     145
2.16       681    527    429     274     191
2.18      1537   1140    920     580     382
2.20      3962   2789   2288    1321     768
2.22      9686   6951   5331    3050    1765
2.24     21056  15007  11416    6436    3752
2.26     38267  26874  20562   11561    6637
2.28     55706  39067  29799   16900    9596
2.30     64310  45348  34907   19514   11307
2.32     59707  42021  31802   18299   10180
2.34     44050  31169  23458   13561    7769
2.36     25907  18337  13965    7889    4576
2.38     13059   9341   6997    3978    2401
2.40      6294   4539   3472    1966    1296
2.42      4272   3028   2389    1391     892
2.44      3995   2956   2312    1344     862
2.46      3970   2898   2267    1351     862
2.48      3496   2522   2055    1153     731
2.50      2512   1815   1512     938     613'''
df = pd.read_csv(StringIO(data_str), delim_whitespace=True).set_index('spectra')
xs = df.index.values
rows = df.values
colors = plt.cm.Set1.colors
fig, ax = plt.subplots(figsize=(15, 5))

prev_ord = None
prev_xs = []
prev_rows = []
for x, row in zip(xs, rows):
     ord = np.argsort(row)[::-1]
     if (ord != prev_ord).any():
          if prev_ord is not None:
               for i in prev_ord:
                    ax.fill_between(prev_xs, [r[i] for r in prev_rows], color=colors[i])
          prev_ord = ord
          prev_xs = [x]
          prev_rows = [row]
     else:
          prev_xs.append(x)
          prev_rows.append(row)
if prev_ord is not None:  # plot last chunk
     for i in prev_ord:
          ax.fill_between(prev_xs, [r[i] for r in prev_rows], color=colors[i])

handles = [plt.Rectangle((0, 0), 0, 0, color=color, label=lbl) for color, lbl in zip(colors, df.columns)]
ax.legend(handles=handles)
ax.margins(x=0)
ax.set_ylim(ymin=0)
plt.tight_layout()
plt.show()

相关问题