Matplotlib & Plotly Charts

Matplotlib

通过使用 pictures.add() ,能很容易地把Matplotlib图表当作图片贴进Excel中。

从头开始

最简单的例子都可以归结为下面的模式:

import matplotlib.pyplot as plt
import xlwings as xw

fig = plt.figure()
plt.plot([1, 2, 3])

sheet = xw.Book().sheets[0]
sheet.pictures.add(fig, name='MyPlot', update=True)
_images/mpl_basic.png

注解

如果设置 update=True,就可以做Excel里移动和缩放图表:后续调用 pictures.add() 时如果图表名称相同('MyPlot'),会更新图表,不改变它的位置和大小

全面集成到Excel

RunPython 调用上面的代码并把它绑定到一个按钮上是件水到渠成的事情,并且能够跨平台工作。

不过,在Windows系统上可以通过下面的代码来定义一个 UDF 使得集成度更高:

@xw.func
def myplot(n, caller):
    fig = plt.figure()
    plt.plot(range(int(n)))
    caller.sheet.pictures.add(fig, name='MyPlot', update=True)
    return 'Plotted with n={}'.format(n)

导入这个UDF函数并在B2上调用它,图表会随着B1的值而变化:

_images/mpl_udf.png

属性

大小、位置和其他属性可以通过 pictures.add() 的参数设定,也可以通过对返回的图片对象进行操作,参见 xlwings.Picture().

例如:

>>> sht = xw.Book().sheets[0]
>>> sht.pictures.add(fig, name='MyPlot', update=True,
                     left=sht.range('B5').left, top=sht.range('B5').top)

或:

>>> plot = sht.pictures.add(fig, name='MyPlot', update=True)
>>> plot.height /= 2
>>> plot.width /= 2

获得Matplotlib图片

下面是一些如何取得matplotlib figure 对象的例子:

  • 通过PyPlot接口:

    import matplotlib.pyplot as plt
    fig = plt.figure()
    plt.plot([1, 2, 3, 4, 5])
    

    或:

    import matplotlib.pyplot as plt
    plt.plot([1, 2, 3, 4, 5])
    fig = plt.gcf()
    
  • 通过面向对象接口:

    from matplotlib.figure import Figure
    fig = Figure(figsize=(8, 6))
    ax = fig.add_subplot(111)
    ax.plot([1, 2, 3, 4, 5])
    
  • 通过Pandas:

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
    ax = df.plot(kind='bar')
    fig = ax.get_figure()
    

Plotly static charts

Prerequisites

In addition to plotly, you will need kaleido, psutil, and requests. The easiest way to get it is via pip:

$ pip install kaleido psutil requests

or conda:

$ conda install -c conda-forge python-kaleido psutil requests

See also: https://plotly.com/python/static-image-export/

How to use

It works the same as with Matplotlib, however, rendering a Plotly chart takes slightly longer. Here is a sample:

import xlwings as xw
import plotly.express as px

# Plotly chart
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species")

# Add it to Excel
wb = xw.Book()
wb.sheets[0].pictures.add(fig, name='IrisScatterPlot', update=True)
_images/plotly.png