保存PDF时的matplotlib线宽

时间:2013-04-18 21:28:24

标签: python pdf matplotlib dpi

我的数字具有一些对线宽敏感的相当精细的功能。我希望将这个数字保存为一个可以轻松打印的PDF(即接收器侧没有缩放,只需要Command + P和go)。不幸的是,当我设置figsize =(8.5,11)以正确调整PDF的大小以进行打印时,matplotlib会选择一个非常粗的默认线宽和文本大小,这会使绘图变得混乱(图例太大而且条形图中的线条交叠)。如果我设置figsize =(17,22),我将得到一个非常可行的默认线宽,并在将PDF缩放到50%进行打印后进行文本化。这就是我一直在使用的,但是由于政治原因,这个解决方案变得不可行,而且每次我做出改变时我都不想在插图画家中扩展PDF。

如果我可以使用位图,我可以通过设置figsize =(17,22)并将dpi设置为目标dpi的一半来实现所需的结果,但这不适用于PDF,因为dpi参数似乎被忽略。我想要一个PDF

  • 看起来像boxes_good.png(带有细线,小文字的大小欺骗的位图)
  • 的尺寸为8.5x11in(或类似打印件)
  • 可以在插图画家中编辑(不是用pdf包装的位图)

我无法帮助,但怀疑有一种简单的方法来拉动"双倍大小,半dpi"保存为PDF时的技巧,但我放弃了让它工作并开始尝试直接操作线宽和文本化。我成功地修改了文本大小而不是线宽。这是我尝试的事情的记录:

# Tried:
# fig.set_size_inches(17,22)
# fig.savefig('boxes.pdf', dpi=100,150,300)
#   dpi parameter has no effect on linewidth, text size, or the PDF's dimensions
# 'markerscale=.5' on plt.legend and pax.legend
#   no effect
# mp.rcParams['font.size']=8
#   worked! made text smaller, now for linewidth...
# mp.rcParams['lines.linewidth']=5
#   no effect
# fig.set_linewidth(5)
#   no effect
# pax.axhline(linewidth=5)
#   only changes x axis not box surrounding subplot
# fig.set_size_inches(8.5,11) immediately before plt.savefig('boxes.pdf')
#   identical results to calling plt.figure(figsize=(8.5,11)) in the first place

# I tried passing plt.figure(figsize=(17,22)) and swapping it to 8.5x11 using
# fig.set_size_inches right before saving, but the lines were thick and the text
# was large in the PDF, exactly as if I had set figsize=(8.5,11) to begin with

这是源文件(我将情节简化为必需品,因此明显的样式解决方法可能不是可行的解决方案)

import numpy as np
import matplotlib as mp
import matplotlib.pyplot as plt

x = np.arange(200)
bottom_red_bar = -np.random.random(200)
bottom_black_bar = np.random.random(200) * bottom_red_bar

fig = plt.figure()
for subplotnum in [1,2,3]:
    pax = plt.subplot(310+subplotnum)
    pax.set_ylim([-1,1])
    bot_rb = pax.bar(x,         bottom_red_bar,1,color='r')
    bot_bb = pax.bar(x+(1-.3)/2,bottom_black_bar,.3,color='k')
    pax.legend([bot_rb,bot_bb],['Filler Text 1','Filler Text 2'],loc=4)

fig.set_size_inches(8.5,11)
fig.savefig('boxes_bad.png',dpi=300)  # Lines are too thick

fig.set_size_inches(17,22)
fig.savefig('boxes_good.png',dpi=150)  # Lines are just right

fig.set_size_inches(8.5,11)
plt.savefig('boxes.pdf')  # Lines are too thick

fig.set_size_inches(17,22) # Lines are just right
plt.savefig('boxes.pdf')   # but the PDF needs scaling before printing

所以我想要调整整个数字的线宽或者让matplotlib保存带有与figsize不同的维度元数据的pdf的方法。有什么建议吗?

2 个答案:

答案 0 :(得分:8)

感谢Marius,一旦我获得15点声望,我就会立即投票。虽然你的rcParams与我想做的不完全匹配,但是rcParams本身是正确的看点,所以我通过rcParams.keys()列出了包含'linewidth'的rcParams:

>>> [s for s in mp.rcParams.keys() if 'linewidth' in s]
['axes.linewidth', 'grid.linewidth', 'lines.linewidth', 'patch.linewidth']

经过一些实验,我找到了每个参数控制的内容:
mp.rcParams ['axes.linewidth']:整个地块周围的方形(不是刻度线,不是y = 0线)
mp.rcParams ['grid.linewidth']:未测试,可能是网格宽度
mp.rcParams ['lines.linewidth']:使用pyplot.plot制作的线图宽度
mp.rcParams ['patch.linewidth']:矩形笔划的宽度,包括pyplot.bar图的条形图,图例和图条的图例标签
mp.rcParams ['xtick.minor.width']:小xticks的线宽(yticks相似)
mp.rcParams ['xtick.major.width']:大xticks的线宽(yticks类似)

我使用的特定解决方案是

mp.rcParams['axes.linewidth'] = .5
mp.rcParams['lines.linewidth'] = .5
mp.rcParams['patch.linewidth'] = .5

答案 1 :(得分:6)

我建议通过rcParams(或你的matplotlibrc文件)调整线宽等参数:

# mp.rcParams['figure.figsize'] = fig_size  # set figure size
mp.rcParams['font.size'] = font_size
mp.rcParams['axes.labelsize'] = font_size
mp.rcParams['axes.linewidth'] = font_size / 12.
mp.rcParams['axes.titlesize'] = font_size
mp.rcParams['legend.fontsize'] = font_size
mp.rcParams['xtick.labelsize'] = font_size
mp.rcParams['ytick.labelsize'] = font_size

我通常使用标准figure.figsize (8,6)和轴对象中的线宽1/12的字体大小(例如。font_size = 16当我包含两篇论文中的情节。)

请记住,矢量图形并不意味着缩放时所有线条和字母总是具有相同的大小。这意味着你可以在不失去质量或锐度的情况下进行扩展(粗略地说)。