2013-11-04 45 views
17

使用乳膠我設置usetext = true在matplotlib使用乳膠在我的陰謀管理字型佈局。現在X軸和xticklabel之間的空間對於圖中所示的正值和負值是不同的。差異在matplotlib

是否有可能得到同樣的空間呢?

例子:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.linspace(-10.0, 10.0, 100) 
s = np.cos(t) 

plt.rc('text', usetex=True) 

plt.rc('font', family='serif', size=30) 
plt.plot(t, s) 

plt.show() 

enter image description here

+2

有沒有簡單的方法來實現這一目標,因爲文本與'dvipng'外部處理,並將得到的圖像插入圖形。這些沒有任何空白。你必須做的是將xtick標籤對齊設置爲'右',然後向右移位。但我無法得到這個額外的轉變工作。 – Christoph

+0

問題在於如何從PS邊界框中推斷文本的輪廓。它是對齊的大綱框,而不是文本本身。我想你必須深入挖掘才能改變這種行爲。 – mdurant

+3

不努力「過度工程」你的陰謀,他們已經整齊。 –

回答

0

我解決一些小問題這樣是爲了節省情節爲SVG,然後在我最喜歡的矢量圖形程序(如InkScape)編輯方式。這將允許您選擇繪圖的各個部分並移動它們,同時保留高質量的矢量圖形。

0

這是一種「哈克」的做法,我不確定它爲什麼修復它,但使用matplotlib.tickerFormatStrFormatter似乎解決了這個問題。唯一不同的是字體重量看起來粗體。我似乎無法改變這種情況,但也許你可以使用它。

import numpy as np 
import matplotlib.ticker as mtick 
import matplotlib.pyplot as plt 

t = np.linspace(-10.0, 10.0, 100) 
s = np.cos(t) 

plt.rc('text', usetex=True) 
plt.rc('font', family='serif', size=30) 

fig = plt.figure() 
ax1 = fig.add_subplot(111) 
ax1.plot(t, s) 

fmtx = '%.0f%%' 
fmty = '%.1f%%' 
xticks = mtick.FormatStrFormatter(fmtx) 
yticks = mtick.FormatStrFormatter(fmty) 
ax1.xaxis.set_major_formatter(xticks) 
ax1.yaxis.set_major_formatter(yticks) 
plt.show() 

enter image description here

+0

這在某種程度上是有效的,因爲它爲TeX標籤使用文本模式而不是數學模式,而文本模式減號不具有相同的問題。 – cge

-1

所以(可惜)我只設法想出了另一個 「哈克」 解決方案,但我想我會分享:

import numpy as np 
import matplotlib as mplib 
import matplotlib.pyplot as plt 
import types 

# set up few plot options 
plt.rc('text', usetex=True) 
plt.rc('font', family='serif', size=30) 

# get some data to plot 
t = np.linspace(-10.0, 10.0, 100) 
s = np.cos(t) 

# plot things 
fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.plot(t, s) 

# define and register onresize callback to handle new ticks that appear on resize 
def onresize(event): 
    SHIFT = 0.5 
    for label in ax.get_xticklabels(): 
     #print(label.get_text()) # test to see if new ticks appear as expected 
     label.set_ha('right') 
     label.customShiftValue = SHIFT 
     label.set_x = types.MethodType(
       lambda self, x: mplib.text.Text.set_x(self, x+self.customShiftValue), 
       label) 

cid = fig.canvas.mpl_connect('resize_event', onresize) 

# hold plot open 
plt.show(block=True) 

產生以下輸出

alt_img


因此,讓我解釋我在這裏做了什麼。最初,我重複了for -loop中的xticklabels,並使用label.set_ha('right')將所有xticklabels水平對齊到右側。然而,標籤全部填充,我沒有縮小邊界框(甚至不知道它是否以這種方式工作!)。因此,我決定註冊一個onresize回調函數,因爲在調整大小時可能會出現新的xticklabels。然後,我增加了set_x函數(代碼是借用:https://stackoverflow.com/a/33688795/2402281,貸記給他們)。唯一可以不用手動調整SHIFT變量的方法就是讓畫布大小做一些有意義的計算,範圍在[0.4,0.6],這似乎是很好的偏移值(經驗性測試...)。

即使它只是另一個「哈克」解決方案,它可以幫助找到合適的答案!我希望它有幫助。

+0

這仍然存在相同的問題。除非我感到困惑,否則它是軸和標籤之間的* vertical *空間是問題,而不是水平對齊。這是[已知錯誤](https://github.com/matplotlib/matplotlib/issues/6323)。 – cge

+0

感謝您的反饋@cge。對那些投了我票的人......爲什麼?我試圖提供一個解決方案,甚至承認它是一個骯髒的黑客... – Thomas

1

這是不幸的是,這個bug已經存在了這麼久,而且大多數的答案想到這裏的問題是關於水平對齊而不是垂直間距。

The bug是已知的,並且有一個補丁可以修復它,但它並未被合併,只是被列爲需要在過去的一年半中進行審查。

有趣的是,這是相當混亂的錯誤。這個問題最初出現的原因在於,出於某種原因,TeX給出了一個減號(和其他數學符號)的下降值,表明它延伸到了基線以下。用於在柵格後端創建標籤的dvipng只是裁剪可見的,所以這沒關係。但爲了保持實際上具有後代的對齊,matplotlib有一個單獨的系統dviread,它從dvi文件本身讀取值。這會帶來奇怪的下降值。然後matplotlib的對齊系統,認爲PNG的一部分是假設低於基線,將其下移。

修復bug報告非常簡單,但我不完全確定它是如何工作的。我試過了,但是,它確實有效。

當然,這個問題在2013年被問到了,所以看起來這個補丁不會很快適用。那麼有什麼選擇?

一個簡單的方法是在工作時忽略對齊問題,但是在執行演示輸出時使用pdf後端。如果你想要圖像,你可以隨時使用其他軟件進行轉換。 pdf後端不會遇到同樣的問題,因爲它完全不同地處理TeX部分。

另一種選擇是調整消極xticks的位置。從理論上講,你可以從_get_layout中調出確切的調整值,這會給你下降值,但我不確定如何轉換值。因此,這裏的只是虎視眈眈的對齊的示例:

import numpy as np 
import matplotlib.pyplot as plt 

t = np.linspace(-10.0, 10.0, 100) 
s = np.cos(t) 

i = [-10,-5,0,5,10] 

plt.rc('text', usetex=True) 

plt.rc('font', family='serif', size=30) 
plt.plot(t, s) 

for n,l in zip(*plt.xticks()): 
    if n<0: l.set_position((0,0.014))