如何在JupyterLab中合理缩放matplotlib内嵌图形?
解决JupyterLab中Matplotlib图形显示过大且导出模糊的问题
我之前从经典Jupyter Notebook转用JupyterLab时也碰到过一模一样的问题!%matplotlib inline下的图总是显得特别大,调figsize又会让字体比例失调,导出PPT还模糊,折腾了好一阵才搞明白根源和解决办法。
问题根源:JupyterLab的图像渲染逻辑
你已经通过实验验证了关键一点:JupyterLab前端不是按figsize的英寸值来显示图像,而是根据figsize × dpi计算出的像素宽度来渲染——只要这个像素宽度不超过浏览器窗口宽度,就会原尺寸显示;超过的话才会被Chrome自动缩放。
而且字体大小只和dpi成正比,和figsize无关,这就是为什么你调小figsize后标签会显得过大的原因。
验证代码(你提供的这段太有用了!)
这段代码能直观展示Lab的显示逻辑,不同组合下的图形大小差异一目了然:
import numpy as np import matplotlib.pyplot as plt %matplotlib inline xys = np.random.multivariate_normal([0.0, 0.0], [[1.0,-0.5],[-0.5,1.0]], 50) for figsize in [(3,2),(6,4)]: for dpi in [25,50,100]: fig = plt.figure(figsize=figsize, dpi=dpi) ax = fig.add_subplot(1,1,1) ax.scatter(xys[:,0], xys[:,1]) ax.set_title('figsize = {}, dpi = {}'.format(figsize, dpi))
完美解决方案:分离显示与导出的DPI设置
既然Lab的显示由像素总数控制,而导出清晰度由DPI决定,那我们就把这两个场景分开处理:
- JupyterLab内显示:使用较低的
dpi(比如50-100),配合合适的figsize,让生成的像素宽度刚好适配你的浏览器窗口,保证图形和字体比例协调。 - 导出高清图(用于PPT/发布):在保存时单独指定高
dpi(比如300-1200),这样导出的图像像素足够多,放大也不会模糊,而且不会影响Lab里的显示效果。
示例代码
import numpy as np import matplotlib.pyplot as plt %matplotlib inline xys = np.random.multivariate_normal([0.0, 0.0], [[1.0,-0.5],[-0.5,1.0]], 50) # 1. 适配JupyterLab显示的图形:低DPI,保证尺寸适中 fig = plt.figure(figsize=(6, 4), dpi=75) # 75DPI生成的图宽度=6*75=450像素,刚好适配大部分窗口 ax = fig.add_subplot(1,1,1) ax.scatter(xys[:,0], xys[:,1]) ax.set_title('JupyterLab显示专用:尺寸适中,字体比例协调') plt.show() # 2. 导出高清图:单独设置高DPI,不影响显示 fig.savefig('scatter_highres.jpg', dpi=1200, bbox_inches='tight') # bbox_inches='tight'可以避免保存时标题、标签被截断,非常实用
进阶:写个工具函数一键搞定
如果经常需要切换显示和导出,可以封装一个函数,省去重复代码:
def plot_with_display_and_save(figsize=(6,4), display_dpi=75, save_dpi=1200, filename='plot.jpg'): fig = plt.figure(figsize=figsize, dpi=display_dpi) ax = fig.add_subplot(1,1,1) ax.scatter(xys[:,0], xys[:,1]) ax.set_title(f'显示DPI={display_dpi},导出DPI={save_dpi}') plt.show() # 保存时用高DPI,同时处理边界截断问题 fig.savefig(filename, dpi=save_dpi, bbox_inches='tight', facecolor='white') # 调用示例 plot_with_display_and_save(figsize=(8,5), display_dpi=60, save_dpi=900, filename='my_custom_plot.jpg')
这样就能同时满足Lab里的显示需求和导出高清图的需求啦!
内容的提问来源于stack exchange,提问作者Ymareth
相关产品推荐
相关产品推荐

