Маркировка диапазона данных в matplotlib - PullRequest
3 голосов
/ 14 июля 2020

У меня есть график matplotlib, который хотел бы пометить диапазоны данных по оси y одной меткой и аннотировать каждый диапазон чем-то вроде фигурной скобки. Здесь есть аналогичный вопрос , но этот подход не работает, если скобка должна находиться за пределами графика, а в пространстве, где находятся метки осей, что необходимо в моем случае, поскольку я хочу аннотировать тепловую карту, где все пространство внутри графика уже занято.

Что у меня есть:

enter image description here

What I want:

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

код для примера графика:

import numpy as np
import matplotlib.pyplot as plt

arr = np.array([[3,4],[2,3.5],[10,11],[9,10]])

fig = plt.figure()
ax = fig.add_subplot(111)

ax.imshow(arr)

ax.set_title("example plot")
ax.set_yticklabels([])
ax.set_yticks([])

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Я не могу делать продвинутые вещи, которые вы видите в комментариях, но я пытался делать все, что могу, с «латексом». Это не ваш ответ, но я поделюсь им для справки.

import numpy as np
import matplotlib.pyplot as plt

arr = np.array([[3,4],[2,3.5],[10,11],[9,10]])

fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111)

ax.imshow(arr)

ax.set_title("example plot")
ax.text(-1.10, 0.25, r'$group 1$', fontsize=24, ha='left', va='center', rotation='horizontal', transform=ax.transAxes)
ax.text(-0.35, 0.25, '$\{$', fontsize=72, ha='left', va='center', rotation='horizontal', transform=ax.transAxes)
ax.text(-1.10, 0.75, r'$group 2$', fontsize=24, ha='left', va='center', rotation='horizontal', transform=ax.transAxes)
ax.text(-0.35, 0.75, '$\{$', fontsize=72, ha='left', va='center', rotation='horizontal', transform=ax.transAxes)
ax.set_yticklabels([])
ax.set_yticks([])

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

0 голосов
/ 14 июля 2020

Благодаря предложению j_4321 и коду из ответа в связанном вопросе я придумал следующее решение. Это не идеально, так как мне все еще нужно вручную настраивать значения для графиков разного размера. Ему также нужен автоматический c аспект, который несколько искажает тепловую карту:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

def draw_brace(ax, span, text, axis):
    """Draws an annotated brace on the axes."""
    # axis could be reversed
    xx = ax.get_xlim()
    xmin = np.min(xx)
    xmax = np.max(xx)
    yy = ax.get_ylim()
    ymin = np.min(yy)
    ymax = np.max(yy)
    xspan = xmax - xmin
    yspan = ymax - ymin
    
    if axis=="y":
        tspan = yspan
        ospan = xspan
        omin  = xmin
    else:
        ospan = yspan
        omin  = ymin
        tspan = xspan
    
    amin, amax = span
    span = amax - amin
    
    resolution = int(span/tspan*100)*2+1 # guaranteed uneven
    beta = 300./tspan # the higher this is, the smaller the radius
    
    x = np.linspace(amin, amax, resolution)
    x_half = x[:resolution//2+1]
    y_half_brace = (1/(1.+np.exp(-beta*(x_half-x_half[0])))
                    + 1/(1.+np.exp(-beta*(x_half-x_half[-1]))))
    y = np.concatenate((y_half_brace, y_half_brace[-2::-1]))
    y = omin + (.05*y - .01)*ospan # adjust vertical position

    #ax.autoscale(False)
    if axis == "y":
        ax.plot(-y +1 , x, color='black', lw=1)
        ax.text(0.8+ymin+.07*yspan, (amax+amin)/2., text, ha='center', va='center')
    else:
        ax.plot(x, y, color='black', lw=1)
        ax.text((amax+amin)/2.,ymin+.07*yspan, text, ha='center', va='center')
    

arr = np.array([[3,4],[2,3.5],[10,11],[9,10]])
fig = plt.figure()

gs = fig.add_gridspec(nrows=1, ncols=2, wspace=0,width_ratios=[1,4])

ax2 = fig.add_subplot(gs[:, 1])

ax2.imshow(arr)
ax2.set_title("example plot")

ax2.set_yticklabels([])
ax2.set_yticks([])
ax2.set_xticklabels([])
ax2.set_aspect('auto')

ax1 = fig.add_subplot(gs[:, 0], sharey=ax2)
ax1.set_xticks([])
ax1.set_xticklabels([])
ax1.set_aspect('auto')
ax1.set_xlim([0,1])
ax1.axis('off')
draw_brace(ax1, (0, 1), 'group1',"y")
draw_brace(ax1, (2, 3), 'group2',"y")

fig.subplots_adjust(wspace=0, hspace=0)

Это создает следующий график: введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...