Ошибка Python plot : annotate () получила несколько значений для аргумента ‘xy’

#python #matplotlib #annotate

#python #matplotlib #аннотировать

Вопрос:

На моем графике я пытаюсь аннотировать несколько значений в каждой точке.

 weights = [np.array([w, 1-w]) for w in np.linspace(0, 1, 5)]

mu = [0.5, 0.25]

def portfolio_return(weights, returns):
    return weights.T @ returns

rets = [portfolio_return(w, mu) for w in weights]

S = [[0.493, 0.11], [0.11, 0.16]]
def portfolio_vol(weights, cov):
    return (weights.T @ cov @ weights)**0.5

vols = [portfolio_vol(w, S) for w in weights]

import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'

markers_on = [1, 3]
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(vols, rets, 'g-')

for marker in markers_on:
    plt.plot(vols[marker], rets[marker], 'bs')
    w1, w2 = weights[marker][0], weights[marker][1]
    ax.annotate(f'w = ({w1:.1f}, {w2:.1f})', (w1, w2), xy=(vols[marker] .08, rets[marker]-.03))

plt.xlabel('Risk')
plt.ylabel('Return')
plt.show()
  

Это возвращает ошибку —

 ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-0e29da296b76> in <module>
     11     plt.plot(vols[marker], rets[marker], 'bs')
     12     w1, w2 = weights[marker][0], weights[marker][1]
---> 13     ax.annotate(f'w = ({w1:.1f}, {w2:.1f})', (w1, w2), xy=(vols[marker] .08, rets[marker]-.03))

TypeError: annotate() got multiple values for argument 'xy'
  

Новое в Python plot. Все, что я пытаюсь сделать, это аннотировать две точки на графике, в каждой из которых показаны оба веса.

 ---------------------------------------------------------------------------
  

Примечание — внесены следующие изменения после комментария @ewong.

 for marker in markers_on:
    plt.plot(vols[marker], rets[marker], 'bs')
    w1, w2 = weights[marker][0], weights[marker][1]
    ax.annotate(r'w = ({w1:%.2f}, {w2:%.2f})', (w1, w2))
  

Ошибки нет, что хорошо. К сожалению, хотя он отмечает две позиции, веса не отображаются.

Также перед отображением графика остается значительное количество пробелов. Я должен прокрутить вниз в jupyter notebook.

----------------------------------------------------------------------------------

Внесены дальнейшие изменения. Получение графика со всеми тремя маркерами. Но не веса.

 for marker in markers_on:
    plt.plot(vols[marker], rets[marker], 'bs')
    w1, w2 = weights[marker][0], weights[marker][1]
    text = f'w = ({w1:.2f}, {w2:.2f})', (w1, w2)
    ax.annotate(s = text, xy=(vols[marker] .08, rets[marker]-.03))

  

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

1. aiui, из matplotlib.org/3.1.0/api/_as_gen /… , annotate() обрабатывает (w1, w2) как xy , поэтому повторное указание xy является ошибкой.

2. Спасибо @ewong внес предложенное вами изменение. Ошибки нет. Значения не отображаются. Смотрите отредактированную версию вопроса.

3. Вы могли бы присвоить f'w = ({w1:.1f}, {w2:.1f})', (w1, w2) временной переменной и использовать эту временную переменную в качестве текста в ax.annotate() .

4. @Ynjxsjmh не могли бы вы, пожалуйста, показать мне, как это сделать? Как бы выглядел код?

5. text = f'w = ({w1:.1f}, {w2:.1f})', (w1, w2) n ax.annotate(text=text, xy=(vols[marker] .08, rets[marker]-.03)) . Вы могли бы сослаться на Axes.annotate() для значения text аргумента.

Ответ №1:

Причина, по которой вы не увидели вес, заключается в том, что вы корректируете место текста с помощью xy=(vols[marker] .08, rets[marker]-.03) . Судя по вашей картинке, я заметил, что максимальное значение x равно 0.0225 . 0.08 больше 0.0225 , поэтому текст выходит за рамки.

 import numpy as np
import matplotlib.pyplot as plt

weights = [np.array([w, 1-w]) for w in np.linspace(0, 1, 5)]

mu = [0.5, 0.25]

def portfolio_return(weights, returns):
    return weights.T @ returns

rets = [portfolio_return(w, mu) for w in weights]

S = [[0.493, 0.11], [0.11, 0.16]]
def portfolio_vol(weights, cov):
    return (weights.T @ cov @ weights)**0.5

vols = [portfolio_vol(w, S) for w in weights]


markers_on = [1, 3]
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(vols, rets, 'g-')

for marker in markers_on:
    plt.plot(vols[marker], rets[marker], 'bs')
    w1, w2 = weights[marker][0], weights[marker][1]
    text = f'w = ({w1:.1f}, {w2:.1f})'
    ax.annotate(text, xy=(vols[marker] .005, rets[marker]-0.005))

plt.xlabel('Risk')
plt.ylabel('Return')
plt.show()
  

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