Matplotlib два разных цвета в одном аннотате
Я пытаюсь создать фигуру на python и сделать так, чтобы один и тот же аннонированный текст имел два цвета, половина аннотации будет синей, а другая половина будет красной.
Я думаю, что код объясняет сам. У меня 3 линии 1 зеленый с зеленым аннонитом, 1 синий с синим аннотация.
Третий красный - это суммирование графика 1 и графика 2, и я хочу, чтобы он имел половину аннотации синего и половины зеленого.
ipython -pylab
x=arange(0,4,0.1)
exp1 = e**(-x/5)
exp2 = e**(-x/1)
exp3 = e**(-x/5) +e**(-x/1)
figure()
plot(x,exp1)
plot(x,exp2)
plot(x,exp1+exp2)
title('Exponential Decay')
annotate(r'$e^{-x/5}$', xy=(x[10], exp1[10]), xytext=(-20,-35),
textcoords='offset points', ha='center', va='bottom',color='blue',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0.95',
color='b'))
annotate(r'$e^{-x/1}$', xy=(x[10], exp2[10]), xytext=(-5,20),
textcoords='offset points', ha='center', va='bottom',color='green',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.5',
color='g'))
annotate(r'$e^{-x/5} + e^{-x/1}$', xy=(x[10], exp2[10]+exp1[10]), xytext=(40,20),
textcoords='offset points', ha='center', va='bottom',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.5',
color='red'))
Возможно ли это?
Ответы
Ответ 1
Вы можете использовать r'$\textcolor{blue}{e^{-x/5}} + \textcolor{green}{e^{-x/1}}$'
, чтобы сделать текст наполовину синим, наполовину зеленым. Используя свой собственный код, например:
![enter image description here]()
Изображение генерируется с помощью следующего кода. Тестирование с помощью matplotlib v2.1.2 со стандартными настройками matplotlibrc
.
import matplotlib as matplotlib
matplotlib.use('pgf')
matplotlib.rc('pgf', texsystem='pdflatex') # from running latex -v
preamble = matplotlib.rcParams.setdefault('pgf.preamble', [])
preamble.append(r'\usepackage{color}')
from numpy import *
from matplotlib.pyplot import *
x=arange(0,4,0.1)
exp1 = e**(-x/5)
exp2 = e**(-x/1)
exp3 = e**(-x/5) +e**(-x/1)
figure()
plot(x,exp1)
plot(x,exp2)
plot(x,exp1+exp2)
title('Exponential Decay')
annotate(r'$e^{-x/5}$', xy=(x[10], exp1[10]), xytext=(-20,-25),
textcoords='offset points', ha='center', va='bottom',color='blue',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0.95',
color='b'))
annotate(r'$e^{-x/1}$', xy=(x[10], exp2[10]), xytext=(25,20),
textcoords='offset points', ha='center', va='bottom',color='green',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.5',
color='g'))
annotate(r'$\textcolor{blue}{e^{-x/5}} + \textcolor[rgb]{0.0, 0.5, 0.0}{e^{-x/1}}$',
xy=(x[10], exp2[10]+exp1[10]), xytext=(40,20),
textcoords='offset points', ha='center', va='bottom',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.5',
color='red'))
savefig('test.png')
Это в основном ваш код со следующими изменениями:
- Вам нужно использовать
pgf
бэкэнд.
- Используйте пакет
color
в pgf.preamble
- Там есть некоторые совпадения с 1-й и 2-й аннотациями, поэтому
xytext
изменяется.
color='g'
во второй аннотации на самом деле не использовал чистый "зеленый" цвет, такой как (0, 255, 0) rgb. \textcolor[rgb]{0.0, 0.5, 0.0}
делает его похожим.
Ответ 2
Я не думаю, что вы можете иметь несколько цветов в одной аннотации, поскольку, насколько я знаю, annotate
принимает только один текстовый объект в качестве параметра, а текстовые объекты поддерживают только одиночные цвета. Итак, насколько мне известно, нет "родного" или "элегантного" способа автоматического выполнения этого.
Однако существует обходное решение: вы можете иметь несколько текстовых объектов, помещенных произвольно в граф. Итак, вот как я это сделаю:
fig1 = figure()
# all the same until the last "annotate":
annotate(r'$e^{-x/5}$'+r'$e^{-x/1}$', xy=(x[10], exp2[10]+exp1[10]), xytext=(40,20),
textcoords='offset points', ha='center', va='bottom',color='white',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.5',
color='r'))
fig1.text(0.365, 0.62, r'$e^{-x/5}$', ha="center", va="bottom", size="medium",color="blue")
fig1.text(0.412, 0.62, r'$e^{-x/1}$', ha="center", va="bottom", size="medium",color="green")
Что я сделал:
- Я установил аннотацию
color='black'
;
- Я создал два текстовых объекта в позициях 0.5, 0.5 (что означает центр
fig1
);
- Я вручную изменил позиции до тех пор, пока они не будут грубо перекрываться с черным текстом, сгенерированным
annotate
(который в итоге оказался значением, которое вы видите в двух вызовах text
);
- Я устанавливаю аннотацию
color='white'
, поэтому она не мешает цвету перекрывающегося текста.
Здесь вывод:
![multi-colour annotated graph]()
Это не очень элегантно, и для его настройки требуется некоторое построение графика, но он выполняет свою работу.
Если вам нужно несколько графиков, возможно, есть способ автоматизировать размещение: если вы не храните объект fig1
, координаты для text
становятся фактическими координатами x, y на графике, я нахожу, что с чем сложнее работать, но, возможно, это позволит вам автоматически генерировать их, используя координаты аннотации xy
? Для меня это не проблема, но если вы это сделаете, я бы хотел увидеть код.