Matplotlib不会全屏保存图像

2024-04-23 18:21:41 发布

您现在位置:Python中文网/ 问答频道 /正文

[编辑]根据回答中的评论,这个问题可能与操作系统有关。我在Windows10上。我有Python3.7.1,我使用Anaconda/Spyder

我遵循thisthis主题,试图在保存之前最大化绘图生成的图像。在我的代码中,有效的是spyder figure viewer的绘图确实最大化了。但是,当文件保存到图像中时,图像不会最大化

我怎样才能修好它

我的代码如下:

import matplotlib as mpl
mpl.use('TkAgg') # With this line on: it returns me error. Without: image don't save as it has been shown in plot from spyder.
from datetime import datetime
import constants
import numpy as np
from numpy import *
from shutil import copyfile
from matplotlib.pyplot import *
mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cbook as cbook
import matplotlib.gridspec as gridspec

plt.rcParams['lines.linewidth'] = 3
plt.rcParams.update({'font.size': 60})
plt.rc('axes', labelsize=80)
plt.rc('xtick', labelsize=80) 
plt.rc('ytick', labelsize=60) 
rcParams["savefig.jpeg_quality"] = 40 

dpi_value = 100
mpl.rcParams["savefig.jpeg_quality"] = dpi_value
plt.rc('axes', labelsize=60)
plt.rc('xtick', labelsize=60)
plt.rc('ytick', labelsize=60)

def plot_surface(zValues,xValues,yValues,title,xLabel,yLabel,titleSave,xlog=True,ylog=True,zlog=True):
    # This function plots a 2D colormap.
    # We set the grid of temperatures
    X,Y =np.meshgrid(xValues,yValues)
    zValues=np.transpose(np.asarray(zValues))
    # We need to transpose because x values= column, y values = line given doc
    # We now do the plots of kopt-1
    fig1,ax1=plt.subplots()
    if zlog==True:
        pcm1=ax1.pcolor(X,Y,zValues,
                        cmap='rainbow',
                        edgecolors='black',
                        norm=colors.LogNorm(vmin=zValues.min(), vmax=zValues.max()))
    else:
        pcm1=ax1.pcolor(X,Y,zValues,
                        cmap='rainbow',
                        edgecolors='black',
                        norm=colors.Normalize(vmin=zValues.min(),vmax=zValues.max()))
    if xlog==True:
        ax1.set_xscale('log', basex=10)
    if ylog==True:
        ax1.set_yscale('log', basey=10)
        
    ax1.set_title(title)
    ax1.set_ylabel(yLabel)
    ax1.set_xlabel(xLabel)
    
    plt.colorbar(pcm1,extend='max')
    
    figManager = plt.get_current_fig_manager()
    figManager.full_screen_toggle()
    # the solution here 
    plt.tight_layout()
    plt.show()

#    if(constants.save_plot_calculation_fct_parameter==True):
    dpi_value=100
    fig1.savefig(titleSave+".jpg",format='jpg',dpi=dpi_value,bbox_inches='tight')

x=np.arange(0,40)
y=np.arange(0,40)
z=np.random.rand(len(x),len(y))
plot_surface(z,x,y,"AA","BB","CC","name",zlog=False)

plt.show()

spyder中图中的渲染:

enter image description here

从保存的图像中:

enter image description here

[编辑]

我复制粘贴了下面答案中的代码,显示仍然不同。spyder的“图形”窗口:

enter image description here

保存在我的计算机上的图像:

enter image description here

[新编辑]:我根据下面的答案列出了所有有效的后端。它们是:

valid backends:         ['agg', 'nbagg', 'pdf', 'pgf', 'ps', 'qt5agg', 'svg', 'template', 'webagg'] 

唯一可以在spyder中显示图形的是qt5agg。而这张图片并没有按照说明正确保存


Tags: 图像importtruematplotlibasnppltmpl
1条回答
网友
1楼 · 发布于 2024-04-23 18:21:41

解决方法是在plt.show之前添加plt.tight_layout()

运行下面的代码(注意,在我的mac上,我必须使用figManager.full_screen_toggle()而不是figManager.window.showMaximized()

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cbook as cbook
import matplotlib.gridspec as gridspec

# comment this part
plt.rcParams['lines.linewidth'] = 3
plt.rcParams.update({'font.size': 20})
#plt.rc('axes', labelsize=60)
#plt.rc('xtick', labelsize=60)
#plt.rc('ytick', labelsize=60)
#rcParams["savefig.jpeg_quality"] = 40

# I don't have the file so I commented this part
# mpl.rcParams['text.usetex'] = True
# mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']

def plot_surface(zValues,xValues,yValues,title,xLabel,yLabel,titleSave,xlog=True,ylog=True,zlog=True):
    # This function plots a 2D colormap.
    # We set the grid of temperatures
    X,Y =np.meshgrid(xValues,yValues)
    zValues=np.transpose(np.asarray(zValues))
    # We need to transpose because x values= column, y values = line given doc
    # We now do the plots of kopt-1
    fig1,ax1=plt.subplots()
    if zlog==True:
        pcm1=ax1.pcolor(X,Y,zValues,
                        cmap='rainbow',
                        edgecolors='black',
                        norm=colors.LogNorm(vmin=zValues.min(), vmax=zValues.max()))
    else:
        pcm1=ax1.pcolor(X,Y,zValues,
                        cmap='rainbow',
                        edgecolors='black',
                        norm=colors.Normalize(vmin=zValues.min(),vmax=zValues.max()))
    if xlog==True:
        ax1.set_xscale('log', basex=10)
    if ylog==True:
        ax1.set_yscale('log', basey=10)
        
    ax1.set_title(title)
    ax1.set_ylabel(yLabel)
    ax1.set_xlabel(xLabel)
    
    plt.colorbar(pcm1,extend='max')
    
    figManager = plt.get_current_fig_manager()
    figManager.full_screen_toggle()
    # the solution here 
    plt.tight_layout()
    plt.show()

#    if(constants.save_plot_calculation_fct_parameter==True):
    dpi_value=100
    fig1.savefig(titleSave+".jpg",format='jpg',dpi=dpi_value,bbox_inches='tight')

x=np.arange(0,40)
y=np.arange(0,40)
z=np.random.rand(len(x),len(y))
plot_surface(z,x,y,"AA","BB","CC","name",zlog=False)

plt.show()

保存的图像将与弹出的图形相同


更新

字体大小之间的差异似乎是由您使用的matplotlib backend造成的。基于this post可能尝试其他后端将解决此问题。例如,在我的mac上,如果我使用TkAgg后端

import matplotlib as mpl
mpl.use('TkAgg')

弹出屏幕中的图形与保存的图形不同。为了知道机器上有哪些可用的matplotlib backend,您可以使用

from matplotlib.rcsetup import all_backends   

all_backends是您可以尝试的所有可用backend的列表


更新2

基于this wonderful post,受支持的后端与有效后端不同。为了找到所有可以使用的有效后端,我修改了那篇文章中的脚本

import matplotlib.backends
import matplotlib.pyplot as plt
import os.path


def is_backend_module(fname):
    """Identifies if a filename is a matplotlib backend module"""
    return fname.startswith('backend_') and fname.endswith('.py')

def backend_fname_formatter(fname): 
    """Removes the extension of the given filename, then takes away the leading 'backend_'."""
    return os.path.splitext(fname)[0][8:]

# get the directory where the backends live
backends_dir = os.path.dirname(matplotlib.backends.__file__)
# filter all files in that directory to identify all files which provide a backend
backend_fnames = filter(is_backend_module, os.listdir(backends_dir))
backends = [backend_fname_formatter(fname) for fname in backend_fnames]

print("supported backends: \t" + str(backends),'\n')

# validate backends
backends_valid = []
for b in backends:
    try:
        plt.switch_backend(b)
        backends_valid += [b]
    except Exception as e:
        print('backend %s\n%s\n' % (b,e))
        continue
print("valid backends: \t" + str(backends_valid),'\n')

运行此脚本时,打印出的valid backends中的后端是可以应用的后端。对于支持但无效的后端,也将打印出它们无效的原因。例如,在我的Mac上,尽管wxcairo是受支持的后端,但它无效,因为No module named 'wx'

通过在PC上运行脚本找到所有有效的后端后,您可以逐个尝试,也许其中一个将生成所需的输出图形

相关问题 更多 >