Порядок типа маркера matplotlib не соответствует после каждого запуска? - PullRequest
0 голосов
/ 11 декабря 2018

Без изменения кода график будет отличаться.Правильно при первом запуске в свежем ударе, неупорядоченный в следующих циклах.(возможно, он может вернуться к правильному порядку)

Конкретно: Среда: MacOS Mojave 10.14.2, python3.7.1, установленный через homebrew.
Для этого: Сюжет scatter для двух или трех подходовданных на одном и том же axes, каждый с разными markertype и разными colors.Создайте пользовательскую легенду, показывающую, какой набор данных представляет каждый markertype.

Извините, у меня нет достаточно времени для подготовки тестируемого кода (пока), но эта часть, похоже, является проблемой:

markerTypes = cycle(['o', 's', '^', 'd', 'p', 'P', '*'])
strainLegends = []
strains = list(set([idx.split('_')[0] for idx in pca2Plot.index]))
for strain in strains:
    # markerType is fixed here, and shouldn't be passed on to the next python run anyway.
    markerType = next(markerTypes)

    # strainSamples connects directly to strain variable, then data is generated from getting strainSamples:
    strainSamples = [sample for sample in samples if
                     sample.split('_')[0] == strain]
    xData = pca2Plot.loc[strainSamples, 'PC1']
    yData = pca2Plot.loc[strainSamples, 'PC2']
    # See pictures below, data is correctly identified from source

    # both scatter and legend instance use the same fixed markerType
    ax.scatter(xData, yData, c=drawColors[strainSamples],
               s=40, marker=markerType, zorder=3)
    strainLegends.append(Line2D([0], [0], marker=markerType, color='k',
                                markersize=10,
                                linewidth=0, label=strain))
    # print([i for i in ax.get_children() if isinstance(i, PathCollection)])

ax.legend(handles=strainLegends)

Как видите, данные markerType и strain коррелируют с данными.

При первом запуске с python3 my_code.py в bash создается правильная картина: см.круг представляет A, квадрат представляет B see the circle represents A, square represents B A = круг, B = квадрат.Посмотрите на квадрат вокруг (-3, -3.8), эта точка данных взята из набора данных B.

В то время, если я снова запускаю код в том же терминале python3 my_code.py enter image description here Примечание A и B полностьюсосредоточены, некоррелированы.Теперь как легенда: A = квадрат, B = круг.Снова посмотрите на точку данных (-3, -3.8), которая поступает из набора данных B, теперь аннотированного как A.

Если я снова запусту код, он может дать другой результат.

Вот код, который я использовалдля создания аннотации:

dictColor = {ax: pd.Series(index=pca2Plot.index), }
HoverClick = interactionHoverClick(
    dictColor, fig, ax)
fig.canvas.mpl_connect("motion_notify_event", HoverClick.hover)
fig.canvas.mpl_connect("button_press_event", HoverClick.click)

В классе HoverClick у меня есть

def hover(self, event):
    if event.inaxes != None:
        ax = event.inaxes
        annot = self.annotAxs[ax]
        # class matplotlib.collections.PathCollection, here refere to the scatter plotting event (correct?)
        drawingNum = sum(isinstance(i, PathCollection)
                         for i in ax.get_children())
        # print([i for i in ax.get_children() if isinstance(i, PathCollection)])

        plotSeq = 0
        jump = []
        indInd = []
        indIndInstances = []
        for i in range(drawingNum):
            sc = ax.get_children()[i]
            cont, ind = sc.contains(event)
            jump.append(len(sc.get_facecolor()))
            indIndInstances.append(ind['ind'])
            if cont:
                plotSeq = i
                indInd.extend(ind['ind'])

        # here plotSeq is the index of last PathCollection instance that program find my mouse hovering on a datapoint of it.
        sc = ax.get_children()[plotSeq]
        cont, ind = sc.contains(event)

        if cont:
            try:
                exist = (indInd[0] in self.hovered)
            except:
                exist = False
            if not exist:
                hovered = indInd[0]
                pos = sc.get_offsets()[indInd[0]]

                textList = []
                for num in range(plotSeq + 1):
                    singleJump = sum(jump[:num])
                    textList.extend([self.colorDict[ax].index[i + singleJump]
                                     for i in indIndInstances[num]])
                text = '\n'.join(textList)
                annot.xy = pos
                annot.set_text(text)
                annot.set_visible(True)
                self.fig.canvas.draw_idle()
        else:
            if annot.get_visible():
                annot.set_visible(False)
                self.fig.canvas.draw_idle()
# hover

Обратите внимание, что я аннотировал код для печати каждого экземпляра.Это проверено, потому что я подумал, что это может быть порядок экземпляров, который был изменен в другой части кода.Но результат показал как в правильном, так и в неправильном случаях, порядок не изменился.

Кто-нибудь знает, что случилось?Кто-нибудь испытывал это раньше?Что мне делать, если мне нужно очистить память в конце кода?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Я обнаружил эту проблему, вызванную процессом отмены репликации, который я сделал в strains.

# wrong code:
strains = list(set([idx.split('_')[0] for idx in pca2Plot.index]))

# correct code:
strains = list(OrderedDict.fromkeys([idx.split('_')[0] for idx in pca2Plot.index]))

Таким образом, заданный вопрос не был действительным.Спасибо и извините за то, что все изучили это.

0 голосов
/ 11 декабря 2018

Поскольку ваш код неполон, трудно сказать наверняка, но кажется, что порядок маркеров искажен итератором cycle.Почему бы вам просто не попробовать:

markerTypes = ['o', 's', '^']
strainLegends = []

for strain, markerType in zip(strains, markerTypes):
    strainSamples = [sample for sample in samples if sample.split('_')[0] == strain]
    xData = pca2Plot.loc[strainSamples, 'PC1']
    yData = pca2Plot.loc[strainSamples, 'PC2']
    ax.scatter(xData, yData, c=drawColors[strainSamples], s=40, marker=markerType, zorder=3)
    strainLegends.append(Line2D([0], [0], marker=markerType, color='k',
                                markersize=10,
                                linewidth=0, label=strain))
ax.legend(handles=strainLegends)

Это, конечно, предполагает, что strains и markerTypes имеют одинаковую длину, а маркеры находятся в той же позиции в списке, что и значение деформации, которое выхочу назначить их.

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