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)

备注
如果设置 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的值而变化:

属性#
大小、位置和其他属性可以通过 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()
备注
When working with Google Sheets, you can use a maximum of 1 million pixels per picture. Total pixels is a function of figure size and dpi: (width in inches * dpi) * (height in inches * dpi). For example, fig = plt.figure(figsize=(6, 4))
with 200 dpi (default dpi when using pictures.add()
) will result in (6 * 200) * (4 * 200) = 960,000 px. To change the dpi, provide export_options
: pictures.add(fig, export_options={"bbox_inches": "tight", "dpi": 300})
. Existing figure size can be checked via fig.get_size_inches()
. pandas also accepts figsize
like so: ax = df.plot(figsize=(3, 3))
. Note that "bbox_inches": "tight"
crops the image and therefore will reduce the number of pixels in a non-deterministic way. export_options
will be passed to figure.figsave()
when using Matplotlib and to figure.write_image()
when using Plotly.
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
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)
