Две цветовые панели Matplotlib с разными (условными) нормализованными цветовыми картами для одной точечной диаграммы?

#python #matplotlib #data-visualization

Вопрос:

У меня есть набор данных из 5 столбцов: a,b,c,d,e . где тип данных b str , а остальные содержат floats . Осями рассеяния являются столбцы a и e для x и y соответственно. Нормализованная цветовая карта основана на столбце e.

Я хочу добавить две цветовые панели, где цветовая карта заполнения такая же, как на диаграмме рассеяния (конечно!), но числовые метки основаны на столбцах c и d. В одной из моих попыток я попытался создать две фигуры , но заставил первую цветовую полосу брать свои значения со второй фигуры. Но это не сработало.

Мои лучшие попытки-это приведенный ниже код, который генерирует прикрепленное изображение. (на основе приведенных ниже данных) Код использует данные для построения обычной цветовой панели и снова запускает тот же блок для второй цветовой панели, где поверхность маркеров (во второй раз) равна 0 (что забавно ;) ) . Я привязал, чтобы добавить третий цикл. таким образом : один реальный цикл для столбца e и два поддельных цикла с поверхностью маркера равны 0 для цветных полос из данных c и d. (см. Второй блок кода) , теперь заполнение маркеров неверно.

т. е.: 1/Мне нужно нормализовать две цветовые панели из двух разных столбцов, но нормализовать заполнение маркеров с помощью одного столбца. 2/ Я хочу перевернуть вторую ось цветовой панели для ясности. (как если бы у него была обратная нормализованная цветовая карта)

[ПРАВКА]: Чтобы инвертировать вторую цветовую панель, добавьте _r в cmap во втором цикле :

Спасибо всем!

Код 1

 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl from mpl_toolkits.axes_grid1 import make_axes_locatable  fig, ax = plt.subplots()  a,b,c,d,e = np.loadtxt('test.txt', delimiter='t', unpack=True,  skiprows=1, dtype=str)  a = a.astype(np.float64) c = c.astype(np.float64) d = d.astype(np.float64) e = e.astype(np.float64) b = list(b) ##################################################### # for c norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max()) cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.Reds) cmap.set_array([]) # for d norm2 = mpl.colors.Normalize(vmin=d.min(), vmax=d.max()) cmap2 = mpl.cm.ScalarMappable(norm=norm2, cmap=mpl.cm.Reds) cmap2.set_array([]) # real for i in range(len(b)):  if b[i] == 'alpha':  sc = ax.scatter(a[i], e[i], marker='o', edgecolors='black',  alpha=0.8, s=120, c=e[i], norm=norm,  cmap='Reds'  )  if b[i] == 'beta':  sc = ax.scatter(a[i], e[i], marker='d', edgecolors='black',  alpha=0.8, s=120, c=e[i], norm=norm,  cmap='Reds'  ) # fake for i in range(len(b)):  if b[i] == 'alpha':  sc1 = ax.scatter(a[i], e[i], marker=',', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=norm2,  cmap='Reds'  )  if b[i] == 'beta':  sc1 = ax.scatter(a[i], e[i], marker=',', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=norm2,  cmap='Reds'  ) years_ax = np.linspace(2000, 2021, 21, endpoint=True, dtype=int) ax.set_xticks(years_ax) plt.xticks(rotation=45) # Rotates X-Axis Ticks by 45-degrees  plt.grid(True, which="both", ls="-", alpha=0.1) plt.xlabel('Years', fontsize=14) plt.ylabel('e', fontsize=14) ax.tick_params(axis='both', which='major', labelsize=14)  divider = make_axes_locatable(ax) cba = divider.new_vertical(size='5%', pad=0.5) cbb = divider.new_vertical(size='5%', pad=0.5)  fig.add_axes(cba) fig.add_axes(cbb)  # add colorbar #1 cba = plt.colorbar(sc, cax=cba, orientation='horizontal') ax.xaxis.set_ticks_position('default') cba.ax.xaxis.set_ticks_position('top') # add colorbar #2 cbb = plt.colorbar(sc1, cax=cbb, orientation='horizontal') cbb.ax.invert_yaxis() ax.xaxis.set_ticks_position('default') cbb.ax.xaxis.set_ticks_position('top')  plt.show()  

Код 2:

 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl from mpl_toolkits.axes_grid1 import make_axes_locatable  fig, ax = plt.subplots()  a,b,c,d,e = np.loadtxt('test.txt', delimiter='t', unpack=True,  skiprows=1, dtype=str)  a = a.astype(np.float64) c = c.astype(np.float64) d = d.astype(np.float64) e = e.astype(np.float64) b = list(b) ##################################################### # for e norme = mpl.colors.Normalize(vmin=e.min(), vmax=e.max()) cmape = mpl.cm.ScalarMappable(norm=norme, cmap=mpl.cm.Reds) cmape.set_array([]) # for c normc = mpl.colors.Normalize(vmin=c.min(), vmax=c.max()) cmapc = mpl.cm.ScalarMappable(norm=normc, cmap=mpl.cm.Reds) cmapc.set_array([]) # for d normd = mpl.colors.Normalize(vmin=e.min(), vmax=e.max()) cmapd = mpl.cm.ScalarMappable(norm=normd, cmap=mpl.cm.Reds_r) cmapd.set_array([]) # real for i in range(len(b)):  if b[i] == 'alpha':  sc = ax.scatter(a[i], e[i], marker='o', edgecolors='black',  alpha=0.8, s=120, c=e[i], norm=norme,  cmap='Reds'  )  if b[i] == 'beta':  sc = ax.scatter(a[i], e[i], marker='d', edgecolors='black',  alpha=0.8, s=120, c=e[i], norm=norme,  cmap='Reds'  ) # fake for c for i in range(len(b)):  if b[i] == 'alpha':  sc = ax.scatter(a[i], e[i], marker='o', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=normc,  cmap='Reds'  )  if b[i] == 'beta':  sc = ax.scatter(a[i], e[i], marker='d', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=normc,  cmap='Reds'  ) # fake for d for i in range(len(b)):  if b[i] == 'alpha':  sc1 = ax.scatter(a[i], e[i], marker=',', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=normd,  cmap='Reds_r'  )  if b[i] == 'beta':  sc1 = ax.scatter(a[i], e[i], marker=',', edgecolors='black',  alpha=0.8, s=0, c=e[i], norm=normd,  cmap='Reds_r'  ) years_ax = np.linspace(2000, 2021, 21, endpoint=True, dtype=int) ax.set_xticks(years_ax) plt.xticks(rotation=45) # Rotates X-Axis Ticks by 45-degrees  plt.grid(True, which="both", ls="-", alpha=0.1) plt.xlabel('Years', fontsize=14) plt.ylabel('e', fontsize=14) ax.tick_params(axis='both', which='major', labelsize=14)  divider = make_axes_locatable(ax) cba = divider.new_vertical(size='5%', pad=0.5) cbb = divider.new_vertical(size='5%', pad=0.5)  fig.add_axes(cba) fig.add_axes(cbb)  # add colorbar #1 cba = plt.colorbar(sc, cax=cba, orientation='horizontal') ax.xaxis.set_ticks_position('default') cba.ax.xaxis.set_ticks_position('top') # add colorbar #2 cbb = plt.colorbar(sc1, cax=cbb, orientation='horizontal') cbb.ax.invert_yaxis() ax.xaxis.set_ticks_position('default') cbb.ax.xaxis.set_ticks_position('top') plt.show()  

Результат: изображение результата

Результат с третьей попытки (с тремя петлями и исправленными перевернутыми столбиками)

вторая попытка

выборка данных-небольшая-:

 a b c d e 2013 alpha 21.8 47 101.3302752 2013 alpha 5 23 105.8 2009 alpha 38 58 88.52631579 2009 alpha 47 77 126.1489362 2009 alpha 188 55 16.09042553 2009 alpha 267 77 22.20599251 2019 alpha 1.67 10 59.88023952 2020 alpha 31.5 57 103.1428571 2013 beta 19 50 131.5789474 2013 beta 26.8 62.5 145.755597 2013 beta 54.5 95 165.5963303 2013 beta 120.1 123 125.970025 2013 beta 147.6 137.5 128.0911247 2007 alpha 14.5 14.5 14.5 2007 alpha 28.7 28 27.31707317 2007 alpha 42.5 40 37.64705882  

Ответ №1:

[Решено] С использованием двух рисунков, где цветовая полоса второго рисунка просто нанесена на второй следующим образом:

 import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl from mpl_toolkits.axes_grid1 import make_axes_locatable  fig, ax = plt.subplots() fig2, ax2 = plt.subplots()  a,b,c,d,e = np.loadtxt('test.txt', delimiter='t', unpack=True, skiprows=1, dtype=str)  a = a.astype(np.float64) c = c.astype(np.float64) d = d.astype(np.float64) e = e.astype(np.float64) b = list(b) ##################################################### # for e norme = mpl.colors.Normalize(vmin=e.min(), vmax=e.max()) cmape = mpl.cm.ScalarMappable(norm=norme, cmap=mpl.cm.Reds) cmape.set_array([]) # for c normc = mpl.colors.Normalize(vmin=c.min(), vmax=c.max()) cmapc = mpl.cm.ScalarMappable(norm=normc, cmap=mpl.cm.Reds) cmapc.set_array([]) # for d normd = mpl.colors.Normalize(vmin=d.min(), vmax=d.max()) cmapd = mpl.cm.ScalarMappable(norm=normd, cmap=mpl.cm.Reds_r) cmapd.set_array([]) # real for i in range(len(b)):  if b[i] == 'alpha':  sc = ax.scatter(a[i], e[i], marker='o', edgecolors='black', alpha=0.8, s=120, c=c[i], norm=normc,  cmap='Reds'  )  if b[i] == 'beta':  sc = ax.scatter(a[i], e[i], marker='d', edgecolors='black', alpha=0.8, s=120, c=c[i], norm=normc,  cmap='Reds'  ) # fake for c for i in range(len(b)):  if b[i] == 'alpha':  sc = ax.scatter(a[i], e[i], marker='o', edgecolors='black', alpha=0.8, s=0, c=e[i], norm=normc,  cmap='Reds'  )  if b[i] == 'beta':  sc = ax.scatter(a[i], e[i], marker='d', edgecolors='black', alpha=0.8, s=0, c=e[i], norm=normc,  cmap='Reds'  ) # # fake for d for i in range(len(b)):  if b[i] == 'alpha':  sc1 = ax2.scatter(a[i], e[i], marker=',', edgecolors='black', alpha=0.8, s=100,c=d[i], norm=normd,  cmap='Reds_r'  )  if b[i] == 'beta':  sc1 = ax2.scatter(a[i], e[i], marker=',', edgecolors='black', alpha=0.8, s=100,c=d[i], norm=normd,  cmap='Reds_r'  ) years_ax = np.linspace(2000, 2021, 21, endpoint=True, dtype=int) ax.set_xticks(years_ax) plt.xticks(rotation=45) # Rotates X-Axis Ticks by 45-degrees  plt.grid(True, which="both", ls="-", alpha=0.1) plt.xlabel('Years', fontsize=14) plt.ylabel('e', fontsize=14) ax.tick_params(axis='both', which='major', labelsize=14)  divider = make_axes_locatable(ax)  cba = divider.new_vertical(size='5%', pad=0.5) cbb = divider.new_vertical(size='5%', pad=0.5)  fig.add_axes(cba) fig.add_axes(cbb)  # add colorbar #1 cba = plt.colorbar(sc, cax=cba, orientation='horizontal') ax.xaxis.set_ticks_position('default') cba.ax.xaxis.set_ticks_position('top') # add colorbar #2 cbb = plt.colorbar(sc1, cax=cbb, orientation='horizontal') cbb.ax.invert_yaxis() ax.xaxis.set_ticks_position('default') cbb.ax.xaxis.set_ticks_position('top') plt.show()