保存PDF时的matplotlib线宽 [英] matplotlib linewidth when saving a PDF

查看:158
本文介绍了保存PDF时的matplotlib线宽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个图形,它具有一些对线宽敏感的相当精细的功能.我想将此图另存为可以轻松打印的PDF(即,接收方不缩放,只需Command + P即可).不幸的是,当我设置figsize =(8.5,11)来正确调整要打印的PDF的大小时,matplotlib会选择非常粗的默认线宽和文本大小,使图表变得混乱(图例太大,条形图中的线也是如此)重叠).如果我设置figsize =(17,22),则在将PDF缩放到50%以进行打印后,将得到一个非常可行的默认线宽和文本大小.这就是我一直在使用的方法,但是由于政治原因,该解决方案变得不可行,我真的不想每次进行更改时都在illustrator中缩放PDF.

I have a figure with some fairly delicate features that are sensitive to linewidth. I want to save this figure as a PDF that can be easily printed (i.e. no scaling on the receiver's side, just Command+P and go). Unfortunately, when I set figsize=(8.5,11) in order to correctly size the PDF for printing, matplotlib picks a very thick default linewidth and text size that mess up the plot (the legend is too large and the lines in the bar chart overlap). If I set figsize=(17,22) I get a very workable default linewidth and textsize after scaling the PDF to 50% for printing. This is what I have been using, but that solution has become unworkable due to politics and I really don't want to scale the PDF in illustrator every time I make a change.

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

If I could work with bitmaps I could achieve the desired result by setting figsize=(17,22) and setting dpi to half of the target dpi, but this does not work for PDFs since the dpi parameter seems to be ignored. I would like a PDF that

  • 看起来像boxs_good.png(带有细线,小文本的大小匹配的位图)
  • 尺寸为8.5x11英寸(或类似的打印尺寸)
  • 可以在illustrator中进行编辑(不是以pdf格式包装的位图)

我不禁怀疑在保存为PDF时有一种简单的方法可以拉出两倍大小,半dpi"的花样,但是我放弃了让它起作用并开始尝试直接操纵线宽和textsizes.我成功修改了textsize,但没有修改线宽.这是我尝试过的事情的记录:

I can't help but suspect that there is an easy way to pull the "double size, half dpi" trick when saving as a PDF, but I gave up on getting that to work and started trying to directly manipulate the linewidths and textsizes. I succeeded in modifying textsize but not linewidth. Here is a record of the things I tried:

# 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

这里是源文件(我将图表简化为基本内容,因此明显的样式变通办法可能不是可行的解决方案)

Here is the sourcefile (I have reduced the plot to essentials, so obvious styling workarounds probably aren't workable solutions)

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.有什么建议吗?

So I'm after a way to either adjust the linewidth of an entire figure or a way to have matplotlib save a pdf with dimension metadata different from figsize. Any suggestions?

推荐答案

感谢Marius,只要获得15点声望,我就会立即投票.虽然您的rcParams与我想做的不太匹配,但是rcParams本身是正确的外观,因此我通过rcParams.keys()列出了包含"linewidth"的rcParams:

Thanks Marius, I'll upvote as soon as I get 15 reputation required to do so. While your rcParams didn't quite match what I wanted to do, rcParams itself was the correct place to look so I listed rcParams containing 'linewidth' via rcParams.keys():

>>> [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)的线宽

After some experimentation, I matched up what each param controlled:
mp.rcParams['axes.linewidth']: the square surrounding the entire plot (not ticks, not the y=0 line)
mp.rcParams['grid.linewidth']: didn't test, presumably grid width
mp.rcParams['lines.linewidth']: the width of line plots made using pyplot.plot
mp.rcParams['patch.linewidth']: the width of rectangle strokes including the bars of a pyplot.bar plot, legends, and legend labels of bar plots
mp.rcParams['xtick.minor.width']: the linewidth of small xticks (yticks similar)
mp.rcParams['xtick.major.width']: the linewidth of large xticks (yticks similar)

我使用的特定解决方案是

The specific solution I wound up using was

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

这篇关于保存PDF时的matplotlib线宽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆