Как построить цветовую полосу по заданной оси в Matplotlib?

#matplotlib #colorbar

Вопрос:

Я хочу построить там подзаголовки на рисунке, используя GridSpec в matplotlib.

В первых строках (различное количество строк) я хочу разместить сетку с кругами.

Во втором последнем ряду я хочу разместить легенду.

В последней строке я хочу разместить цветовую панель.

Но, похоже, моя цветовая панель занимает больше места, чем я дал.

У вас есть какие-нибудь идеи, как это решить?

Вот код для его восстановления:

 from matplotlib import pyplot as plt import matplotlib.cm as matplotlib_cm import numpy as np import matplotlib as mpl import os  def plot_legend_in_given_axis(ax, fontsize):  diameter_labels = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]  row_labels = ['circle']  ax.grid(which="major", color="white", linestyle='-', linewidth=3)  ax.set_aspect(1.0)   for row_index, row_label in enumerate(row_labels):  for diameter_index, diameter_label in enumerate(diameter_labels):  circle=plt.Circle((diameter_index   0.5, row_index   0.5), radius=(diameter_label/(2*1.09)), color='gray', fill=True)  ax.add_artist(circle)   ax.set_xlim([0, len(diameter_labels)])  ax.set_xticklabels([])   ax.tick_params(axis='x', which='minor', length=0, labelsize=12)  ax.set_xticks(np.arange(0, len(diameter_labels), 1))  ax.xaxis.set_ticks_position('bottom')  ax.set_xlabel('Very longnx axis label', fontsize=fontsize, labelpad=5)   ax.set_ylim([0, len(row_labels)])  ax.set_yticklabels([])  ax.tick_params(axis='y', which='minor', length=0, labelsize=12)  ax.set_yticks(np.arange(0, len(row_labels), 1))   ax.grid(which='major', color='black', linestyle='-', linewidth=1)   def main(width, height, xaxis_labels, yaxis_labels):  width_multiply = 1.5  height_multiply = 1.5   figure_width = int(width_multiply * width)  figure_height = int(height_multiply * height)   fig = plt.figure(figsize=(figure_width, figure_height))   grid = plt.GridSpec(width, height, hspace=0, wspace=0)   ax = fig.add_subplot(grid[0:-2, :])  ax.set_aspect(1.0)  legend_ax = fig.add_subplot(grid[-2, :])  plot_legend_in_given_axis(legend_ax, 20)   color_bar_ax = fig.add_subplot(grid[-1, :])  cmap = matplotlib_cm.get_cmap('YlOrRd')  v_min = 2  v_max = 20  norm = plt.Normalize(v_min, v_max)   bounds = np.arange(v_min, v_max   1, 2)  cb = mpl.colorbar.ColorbarBase(color_bar_ax, cmap=cmap, norm=norm, ticks=bounds, spacing='proportional', orientation='horizontal')  cb.ax.tick_params(labelsize=20)  cb.set_label("-log10 (q-value)", horizontalalignment='center', rotation=0, fontsize=20)   plt.xlim([0, width])  ax.set_xticks(np.arange(0, width   1, 1))   plt.ylim([1, height])  ax.set_yticks(np.arange(0, height   1, 1))   # Plot the circles with color in the grid  for yaxis_index, yaxis_label in enumerate(yaxis_labels):  for xaxis_index, xaxis_label in enumerate(xaxis_labels):  circle = plt.Circle((xaxis_index   0.5, yaxis_index   0.5), 0.4, color=cmap(norm(10)), fill=True)  ax.add_artist(circle)   ax.grid()  for edge, spine in ax.spines.items():  spine.set_visible(True)  spine.set_color('black')   figures_path = os.path.join('/Users', 'burcakotlu', 'Desktop')  figFile = os.path.join(figures_path, 'ColorBar_Using_GridSpec.png')  fig.savefig(figFile, dpi=100, bbox_inches="tight")   plt.cla()  plt.close(fig)  width = 5 height = 5 xaxis_labels = ["x%d" %i for i in range(width)] yaxis_labels = ["y%d" %i for i in range(height)] main(width, height, xaxis_labels, yaxis_labels)  

введите описание изображения здесь

Ответ №1:

Эта проблема возникает из-за того, что вы используете plt.xlim([0, width]) и plt.ylim([1, height]) устанавливаете диапазон осей вашего первого подзаголовка (с осями ax ) сразу после определения осей color_bar_ax вашей цветовой панели. Если вместо этого вы используете ax.set_xlim([0, width]) , а ax.set_ylim([1, height]) затем указываете, что теперь ссылаетесь на свой подзаголовок fist ( ax ), и все работает хорошо.

Результаты, которые я получаю от внесения этих изменений, можно увидеть ниже:

введите описание изображения здесь

Дополнительные модификации:

Кроме того, вы можете изменить способ распределения участков на своем GridSpec компьютере таким образом, чтобы между участками и метками не было перекрытия. Ниже я изменил расположение первого подзаголовка в сетке с grid[0:-2, :]) на grid[0:-3, :] , а второй подзаголовок перешел с grid[-2,:] на grid[-3:-1, :] . Затем вывод становится:

введите описание изображения здесь

Комментарии:

1. Спасибо, что указали порядок команд. У меня есть общая проблема в подзаголовках matplotlib, где один из подзаголовков имеет различную ширину и высоту, а другие подзаголовки должны иметь фиксированные размеры. В этом случае сохранение других подзаголовков в фиксированных размерах кажется невозможным.