问题
Friends,
I have 71 ticks that I need to put on a plot (it's the sequence of a protein) and so the ticks need to be staggered, and some are highlighted with asterisks:
________________________________
P o A i I A o g e u n e f e t r
l t x s s L n S q e c O L t e s
* * * ** * * *
I'm using matplotlib.rc('text', usetex=True)
so that I can move the asterisks up (they appear too far down on the axis unless I decrease their \vspace
)
The problem is that the staggering doesn't work, any attempts to put whitespace at the top of the label get eaten by LaTeX. Here's the minimal case (makes each label the same):
tickX = r'\noindent x\\\vspace{0.5cm}\\y\\ \vspace{-0.5cm}\\z'
This works fine, I get the spacing I want. However, I only want x
or y
to appear on the plot, so I \phantom
out the one I don't want:
tickX = r'\noindent \phantom{x}\\\vspace{0.5cm}\\y\\ \vspace{-0.5cm}\\z'
(A list of tickX
is provided to ax.set_xticklabels
, in this example. In the real code, each tick is different.)
But now the newline disappears and the y
s appear just where the x
s should be! I've found \vspace*{}
, but I've had no luck with that either. I've also tried \null
and \mbox{}
.
If I forgo LaTeX and just use ' \ny\nz'
, I get the desired behavior except the z
appears too low and I'm back where I started.
So, my question is: How do I insert a blank line at the top of a LaTeX-processed tick label? Or, equivalently, how do I create a phantom character in LaTeX that can occupy a line by itself at the beginning of the document?
回答1:
Okay, this was a weird one. No amount of searching resulted in matplotlib actually inserting a blank space at the beginning. So, I put a period at the top of each label, thus:
________________________________
................................
P o A i I A o g e u n e f e t r
l t x s s L n S q e c O L t e s
* * * ** * * *
and inserted a \vspace
after each period:
def xTickString(index, sequence, decorations):
ret = r"\noindent "
if(index % 2 == 0): #Put the tick at the top...
ret += r'.\\\vspace{29.1em}\\\makebox[0pt]{'
ret += sequence[index]
ret += r'}\\\vspace{0.2em}\\'
ret += '\makebox[0pt]{\**}' if decorations[index] == '*' else ''
else:
ret += r'.\\\vspace{30em}\\\makebox[0pt]{'
ret += sequence[index]
ret += r'}\\ \vspace{-0.7em}\\'
ret += '\makebox[0pt]{\**}' if decorations[index] == '*' else ''
return ret
Of course with a `\vspace{30em}, the period appears next to the tick and the actual label runs off the page. So, now you offset the label relative to the tick when you configure the axis:
ax.tick_params(axis='x', pad=-494)
which runs the periods off the top of the plot and puts the labels in just the right place.
The zero-width boxes keep the letters in line with their asterisks in the labels, otherwise the spacing gets erratic.
来源:https://stackoverflow.com/questions/30019641/latex-phantom-not-creating-whitespace-in-matplotlib