Функция Excel, созданная с использованием PyXLL, выдает ошибку #num - PullRequest
0 голосов
/ 03 января 2019

Я использую Python с Pyxll для создания функции в Excel, которая должна возвращать график времени.Функция принимает два параметра - «имена» и «даты»

, когда я пытался использовать эту функцию в Excel, выбрав диапазон в столбцах «имена» и «даты», он выдает «#num error. Но яне вижу ошибок при отладке кода Python. В чем может быть проблема?

Вот мой код:

 import matplotlib.pyplot as plt
 import numpy as np
 import matplotlib.dates as mdates
 from datetime import datetime

 from pyxll import xl_func

 @xl_func("str[] names, str[] dates")

def TimeLine_Plot(names, dates): 

  names = np.array(names)
  names = names.reshape(names.size)
  dates = np.array(dates)
  dates = dates.reshape(dates.size)

  dates = [datetime.strptime(ii, "%Y-%m-%dT%H:%M:%SZ") for ii in dates] 
  levels = np.array([-5, 5, -3, 3, -1, 1])
  fig, ax = plt.subplots(figsize=(8, 5))

  # Create the base line
  start = min(dates)
  stop = max(dates)
  ax.plot((start, stop), (0, 0), 'k', alpha=.5)

  for ii, (iname, idate) in enumerate(zip(names, dates)):
     level = levels[ii % 6]
     vert = 'top' if level < 0 else 'bottom'

     ax.scatter(idate, 0, s=100, facecolor='w', edgecolor='k', zorder=9999)
     # Plot a line up to the text
     ax.plot((idate, idate), (0, level), c='r', alpha=.7)
     # Give the text a faint background and align it properly
     ax.text(idate, level, iname,
         horizontalalignment='right', verticalalignment=vert, fontsize=14,
         backgroundcolor=(1., 1., 1., .3))

  ax.set(title="Matplotlib release dates")
  # Set the xticks formatting
  # format xaxis with 3 month intervals
  ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=3))
  ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
  fig.autofmt_xdate()

  # Remove components for a cleaner look
  plt.setp((ax.get_yticklabels() + ax.get_yticklines() +
       list(ax.spines.values())), visible=False)
  plt.show()

 return "Done!"

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Для передачи дат вместо типа "str" ​​используйте тип "date", например:

@xl_func("str[] names, date[] dates")    
def TimeLine_Plot(names, dates):
    ....

Подробнее см. https://www.pyxll.com/docs/userguide/udfs.html#argument-types-and-return-types.

0 голосов
/ 06 января 2019

Вот мой ответ. Не забудьте использовать формат даты в ячейке Excel =% Y-% m-% dT% H:% M:% SZ

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from datetime import datetime 
from pyxll import xl_func

@xl_func("str[] names, str[] dates") 
def TimeLine_Plot(names, dates):

     names = np.array(names)
     names = names.reshape(names.size)
     dates = np.array(dates)
     dates = dates.reshape(dates.size)

     dates = [datetime.strptime(ii, "%Y-%m-%dT%H:%M:%SZ") for ii in dates] 
     levels = np.array([-5, 5, -3, 3, -1, 1])
     fig, ax = plt.subplots(figsize=(8, 5))

     # Create the base line
     start = min(dates)
     stop = max(dates)
     ax.plot((start, stop), (0, 0), 'k', alpha=.5)

     for ii, (iname, idate) in enumerate(zip(names, dates)):
         level = levels[ii % 6]
         vert = 'top' if level < 0 else 'bottom'

         ax.scatter(idate, 0, s=100, facecolor='w', edgecolor='k', zorder=9999)
         # Plot a line up to the text
         ax.plot((idate, idate), (0, level), c='r', alpha=.7)
         # Give the text a faint background and align it properly
         ax.text(idate, level, iname,
         horizontalalignment='right', verticalalignment=vert, fontsize=14,
         backgroundcolor=(1., 1., 1., .3))

    ax.set(title="Matplotlib release dates")
    # Set the xticks formatting
    # format xaxis with 3 month intervals
    ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=3))
    ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
    fig.autofmt_xdate()

    # Remove components for a cleaner look
    plt.setp((ax.get_yticklabels() + ax.get_yticklines() +
          list(ax.spines.values())), visible=False)
    plt.show()

    return "Done!"  
...