当我启用plt.plot([1,2,3], [1,2,3], 'b.')
plt.text(2,2,r'\textbf{(a)} \lambda_{1} value', usetex=True, fontsize=16, fontname='Times New Roman')
plt.savefig('check.eps')
时,我在将matplotlib创建的数字保存为.eps或.ps时遇到问题。如果未启用此功能,则此方法有效。这是一个例子:
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_ps.py", line 671, in draw_tex
thetext = 'psmarker%d' % self.textcnt
AttributeError: 'RendererPS' object has no attribute 'textcnt'
我收到此错误:
usetex=True
启用import pygame
import time
import random
pygame.mixer.pre_init(44100, 16, 2, 4096)
pygame.init()
boop_sound = pygame.mixer.Sound("boop.wav")
display_width = 800
display_height = 600
white = (255,255,255)
black = (0,0,0)
blue = (0, 0, 150)
red = (200,0,0)
light_red = (255,0,0)
yellow = (200,200,0)
light_yellow = (255,255,0)
green = (34,177,76)
light_green = (0, 255, 0)
clock = pygame.time.Clock()
smallfont = pygame.font.SysFont("Rockwell", 25)
medfont = pygame.font.SysFont("Rockwell", 35)
largefont = pygame.font.SysFont("Rockwell", 50)
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("How fast can you tap?")
##icon = pygame.image.load("apple.png")#should be 32x32
##pygame.display.set_icon(icon)
pygame.display.update()
def score(score):
text = smallfont.render("Clicks: "+str(score), True, blue)
gameDisplay.blit(text, [2,0])
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type== pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("How many times can you",
blue,
-80,
"large")
message_to_screen("click the button before the time runs out?",
blue,
-10,
"medium")
#message_to_screen("Press C to play, P to pause or Q to quit.",black,180)
button("Play", 150, 500, 100, 50, green, light_green, action="Play")
button("How to play", 325,500,150,50, yellow, light_yellow, action="How to play")
button("Quit", 550,500,100,50, red, light_red, action="Quit")
pygame.display.update()
clock.tick(15)
def game_over():
game_over = True
while game_over:
for event in pygame.event.get():
if event.type== pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("Out Of Time!",
red,
-100,
"large")
message_to_screen("You clicked: " + str(click) + " times",
blue,
-30)
button("Play Again", 325, 440, 150, 50, green, light_green, action="Play")
button("Quit", 350,500,100,50, red, light_red, action="Quit")
pygame.display.update()
clock.tick(15)
def text_objects(text, color, size):
if size == "small":
textSurface = smallfont.render(text, True, color)
elif size == "medium":
textSurface = medfont.render(text, True, color)
elif size == "large":
textSurface = largefont.render(text, True, color)
return textSurface, textSurface.get_rect()
def text_to_button(msg, color, buttonx, buttony, buttonwidth, buttonheight, size = "small"):
textSurf, textRect = text_objects(msg, color, size)
textRect.center = ((buttonx +((buttonwidth/2)), buttony+(buttonheight/2)))
gameDisplay.blit(textSurf, textRect)
def message_to_screen(msg,color, y_displace=0, size = "small"):
textSurf, textRect = text_objects(msg, color, size)
#screen_text = font.render(msg, True, color)
#gameDisplay.blit(screen_text, [display_width/2, display_height/2])
textRect.center = (display_width/ 2), (display_height / 2) + y_displace
gameDisplay.blit(textSurf, textRect)
def game_controls():
gcont = True
while gcont:
for event in pygame.event.get():
if event.type== pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
message_to_screen("How to play", blue, -100,"large")
message_to_screen("You have to click the button as many times", black, -40)
message_to_screen("as you possible can before the time runs out", black, -20)
button("Play", 150, 500, 100, 50, green, light_green, action="Play")
button("Main", 350,500,100,50, yellow, light_yellow, action="Main")
button("Quit", 550,500,100,50, red, light_red, action="Quit")
pygame.display.update()
clock.tick(15)
def button(text, x, y, width, height, inactive_color, active_color, action = None):
cur = pygame.mouse.get_pos()
clicked = pygame.mouse.get_pressed()
global click
if x + width > cur[0] > x and y + height > cur[1] > y:
pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
if clicked[0] == 1 and action != None:
if action == "Quit":
pygame.quit()
quit()
if action == "How to play":
game_controls()
if action == "Play":
gameLoop()
if action == "Main":
game_intro()
if action == "Click":
click += 1
else:
pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))
text_to_button(text, black, x, y, width, height)
ENDTIMER = pygame.USEREVENT+1
def gameLoop():
gameExit = False
gameOver = False
FPS = 15
click = 0
global click
timed = pygame.time.set_timer(ENDTIMER, 25000)
while not gameExit:
gameDisplay.fill(white)
button("CLICK", display_width/2-100,display_height/2-100, 200,200, red, light_red, action=None)
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.MOUSEBUTTONDOWN:
pygame.mixer.Sound.play(boop_sound)
button("CLICK", display_width/2-100,display_height/2-100, 200,200, red, light_red, action="Click")
button("CLICK", display_width/2-100,display_height/2-100, 200,200, red, light_red, action=None)
elif event.type == ENDTIMER:
game_over()
score(click)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
game_intro()
gameLoop()
时,我也无法使用text命令将字体设置为Time New Roman。
答案 0 :(得分:0)
即使有些迟,如果有人搜索此错误,我也要给出答案。
保存eps
文件将启动RendererPS
后端,该后端检查plt.rcParams['text.usetex']
是否设置为True
来初始化其textcnt
属性。由于usetex
仅为文本对象设置,因此后端不希望必须处理LaTeX并在尝试时会引发错误。可悲的是,在matplotlib的许多地方都存在与LaTeX渲染有关的这种不一致情况。
如果无法使用标准的matplotib功能实现文本格式设置,则一种解决方案是全局设置usetex
:plt.rcParams['text.usetex'] = True
。这会使用LaTeX渲染图形的所有文本(例如,刻度标签或轴标签)。我建议无论如何都要这样做,以保持一致的视觉效果。
关于字体,fontname
参数仅影响标准的matplotlib格式。对于LaTeX渲染,您必须像在LaTeX中一样指定字体。要获得类似Times New Roman的字体,您需要加载相应的程序包,例如mathptmx
times
(不推荐使用plt.rcParams['text.latex.preamble'] = [r'\usepackage{mathptmx}']
包)。当然,该软件包必须安装在本地LaTeX安装中。 matplotlib中的标准字体系列为sans-serif,因此必须使用plt.rcParams['font.family'] = 'serif'
更改为serif。
最终代码是:
import matplotlib.pyplot as plt
# LaTeX setup
plt.rcParams['text.latex.preamble'] = [r'\usepackage{mathptmx}'] # load times roman font
plt.rcParams['font.family'] = 'serif' # use serif font as default
plt.rcParams['text.usetex'] = True # enable LaTeX rendering globally
plt.plot([1,2,3], [1,2,3], 'b.')
plt.text(2,2,r'\textbf{(a)} $\lambda_1$ value', fontsize=16)
plt.savefig('check.eps')
请注意,必须将数学变量括在美元符号$\lambda_1$
中,否则在LaTeX中会出现错误或警告。 (此外,单个字符下标不必放在大括号中。)
作为旁注:在再次关闭usetex
后尝试将图形保存为eps时,遇到了相同的错误。