2013-04-18 17 views
6

Mam figurę z dość delikatnymi rysami, które są wrażliwe na szerokość linii. Chcę zapisać tę liczbę jako plik PDF, który można łatwo wydrukować (tj. Bez skalowania po stronie odbiorcy, wystarczy polecenie + P i przejść). Niestety, kiedy ustawiam figsize = (8.5,11) w celu poprawnego rozmiaru pliku PDF do wydruku, matplotlib wybiera bardzo grubą domyślną szerokość linii i rozmiar tekstu, który zepsuje wykres (legenda jest zbyt duża, a linie na wykresie słupkowym zakładka). Jeśli ustawię figsize = (17,22) otrzymam bardzo funkcjonalną domyślną szerokość linii i textize po skalowaniu pliku PDF do 50% w celu drukowania. Właśnie tego używałem, ale to rozwiązanie stało się niemożliwe z powodu polityki i naprawdę nie chcę skalować pliku PDF w programie Illustrator za każdym razem, gdy wprowadzam zmiany.W przypadku matoffotlib przy zapisywaniu pliku PDF

Gdybym mógł pracować z bitmapami, mógłbym osiągnąć pożądany rezultat, ustawiając figsize = (17,22) i ustawiając dpi na połowę docelowej dpi, ale to nie działa dla plików PDF, ponieważ parametr dpi wydaje się być zignorowany . Chciałbym PDF że

  • wygląda boxes_good.png (rozmiar-oszukany bitmapy z cienkich linii, mały tekst)
  • ma wymiary 8.5x11in (lub wydruki jak to robi)
  • można edytować w programie Illustrator (nie jest bitmapą zawiniętą w pdf)

Nie mogę pomóc, ale podejrzewam, że istnieje łatwy sposób na pobranie "podwójnego rozmiaru, półdpiowej" sztuczki podczas zapisywania jako PDF, ale ja zrezygnowali z tego, aby to zadziałało i zaczęli próbować bezpośrednio manipulować linewidthami i tekstami. Udało mi się zmodyfikować tekst w tekstach, ale nie w całej linii. Oto zapis z rzeczy, ja próbowałem:

# 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 

Oto SourceFile (I zmniejszyły działkę do zasadniczych, więc oczywiste obejścia stylizacji prawdopodobnie nie są wykonalne rozwiązania)

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 

Więc m po sposobie, by dostosować szerokość linii całej figury lub sposób na matplotlib zapisać pdf z metadanymi wymiaru innymi niż figsize. Jakieś sugestie?

Odpowiedz

7

Dzięki Marius, przeprowadzę procedurę, gdy tylko otrzymam 15 punktów reputacji. Podczas gdy twoi rcParams nie bardzo pasuje do tego, co chciałem zrobić sama rcParams było właściwe miejsce, aby wyglądać tak, że wymienione rcParams zawierających „” linewidth poprzez rcParams.keys():

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

Po kilku eksperymentach, ja dopasowane się co każdy param kontroli:
mp.rcParams [ 'axes.linewidth'] kwadratowego wokół całej powierzchni (nie spełnia nie y = 0 linia)
tt.rcParams [ 'grid.linewidth']: nie testowałem, przypuszczalnie szerokość siatki
mp.rcParams [ 'lines.linewidth']: szerokości działek liniowych wykonanych przy użyciu pyplot.plot
mp.rcParams [ 'patch.linewidth']: szerokość prostokątnych kresek zawierających paski wykresu pyplot.bar, legend i legend etykiet słupkowych wykresów słupkowych
mp.rcParams ['xtick.minor.width']: the linewidth małych xticksów (podobnych do podobnych)
mp.rcParams ['xtick.major.width']: szerokość linii dużych xticksów (podobnie jak nick)

Specyficzne rozwiązanie, które otrzymałem, to:

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

Proponuję, aby ustawić parametry takie jak szerokość linii za pośrednictwem rcParams (lub plik 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 

normalnie używam średnia figure.figsize który jest (8,6) i szerokości linii w osi obiektu, który jest 1/12 z rozmiar czcionki (np. font_size = 16, gdy uwzględniam wątki w dokumentach twocolumn).

Pamiętaj, że grafika wektorowa nie oznacza, że ​​wszystkie linie i litery mają zawsze taki sam rozmiar podczas skalowania. Oznacza to, że możesz skalować bez utraty jakości i ostrości (w przybliżeniu).

Powiązane problemy