Я использую matplotlibs plt.axvline для построения вертикальных линий на графике. Я хочу разместить метки на вертикальных линиях прямо на графике, а НЕ в легенде.

Я хочу, чтобы на моем графике были надписи на вертикальных линиях, которые выглядели следующим образом:

like this

Если я увеличиваю определенный раздел, я хочу, чтобы метки вертикальных линий перемещались соответствующим образом, чтобы они все еще были видны на экране. Нравится:

Like this

Кто-нибудь может мне с этим помочь? Это будет высоко ценится!

Мой код пока ниже:

from astropy.io import fits
from astropy.utils.data import download_file
from astropy.table import Table
import matplotlib.pyplot as plt
import numpy as np

class Spectrum:
    # Let's download the data to plot    
    def __init__(self, url):
        self.url = url
        self.hdu_list = fits.open(download_file(url, cache=True), memmap=False)

    # Now lets plot the data
    def plot_spectra(self):
        x = np.array(Table(self.hdu_list[1].data).columns[1])
        x = 10 ** x
        y = np.array(Table(self.hdu_list[1].data).columns[0])
        plt.plot(x, y, 'k', lw=1)

    # Now lets plot the vertical lines, AND THIS IS WHERE I WANT TO ADD LABELS.
    def plot_spectral_types(self):
        my_type = input("Please enter the spectral type to plot (o, b, a, or f): ")
        if my_type is 'o':
            my_type = o_type
        elif my_type is 'b':
            my_type = b_type
        elif my_type is 'a':
            my_type = a_type
        elif my_type is 'f':
            my_type = f_type

        element, wavelength = zip(*my_type)
# Each vertical line's x value is a wavelength. 
# I want the vertical line's label to be the corresponding element.
        for i in wavelength:
            plt.axvline(linewidth=0.25, color='r', x=i)

o_type = [
('NIII', 4097),
('SiIV', 4089),
('H', 4340.5),
('HeI', 4471),
('HeII', 4541),
('NIII', 4632),
('NIII', 4640),
('CIII', 4650),
('HeII', 4686)
]

b_type = [
('SiIV', 4089),
('H', 4101.7),
('HeI', 4121),
('SiII', 4128),
('SiII', 4131),
('H', 4340.5),
('HeI', 4471),
('CIII', 4540),
('HeII', 4541),
('CIII', 4650),
('H', 4861.33)
]

a_type = [
('CaII (K)', 3933.70),
('CaII', 3968.50),
('H', 3970.10),
('H', 4101.70),
('HeI', 4121.00),
('SiII', 4128.00),
('SiII', 4131.00),
('FeI', 4299.00),
('FeI', 4303.00),
('TiII', 4303.00),
('H', 4340.50),
('MgII', 4481.00),
('H', 4861.30),
('H', 6562.70)
]

f_type = [
('CaII', 3933.70),
('CaII', 3968.50),
('H', 3970.10),
('H', 4101.70),
('HeI', 4121.00),
('SiII', 4128.00),
('SiII', 4131.00),
('CaI', 4227.00),
('FeI', 4299.00),
('FeI', 4303.00),
('H', 4340.50),
('CH', 4314.00),
('MgII', 4481.00),
('H', 4861.30),
('H', 6562.70)
]
3
Programmer 1 Авг 2017 в 05:08
1
Я бы изменил заголовок, чтобы он был более полезным для следующего ищущего - «Держите метки внутри графика видимыми при масштабировании», может быть?
 – 
cphlewis
1 Авг 2017 в 22:07

1 ответ

Лучший ответ

Текстовые метки по умолчанию находятся в координатах данных, что, вероятно, является вашей проблемой фиксируем. Вы можете преобразовать значение y в координаты фигуры, относящиеся к текущей оси при масштабировании, и оставить координату x в координатах данных. Более автономный (см. MCVE) пример:

from numpy.random import uniform
from math import sin, pi
import matplotlib.pyplot as plt
import matplotlib.transforms as transforms



fig, ax = plt.subplots()

transDA = transforms.blended_transform_factory(
    ax.transData, ax.transAxes) #  from the transforms tutorial

spectrum = uniform(0,1, 1000) + map(lambda x: sin(2*pi*x/800), range(1000)) #dummy data

ax.plot(range(4000,5000,1), spectrum )

o_type = [
('NIII', 4097),
('SiIV', 4089),
('H', 4340.5),
('HeI', 4471),
('HeII', 4541),
('NIII', 4632),
('NIII', 4640),
('CIII', 4650),
('HeII', 4686)
]

for wavelength in o_type:
        print(wavelength[0],wavelength[1])
        plt.axvline(linewidth=0.25, color='r', x=wavelength[1])
        plt.text(wavelength[1], # x-value from data
                 uniform(0,1), # wiggle the labels 2so they don't overlap
                 wavelength[0], # string label
                 transform = transDA,
                 color='red',
                 family='serif') # the III looked better serif. 

Оригинальный сюжет. Обратите внимание, что первые две метки находятся примерно на полпути вверх по рисунку и, возможно, на четверть вверх по рисунку: введите описание изображения здесь
При увеличении масштаба эти метки перемещаются правильно с увеличенной осью x, но все еще находятся примерно на полпути вверх по фигуре и на четверть вверх по фигуре: введите описание изображения здесь

2
cphlewis 1 Авг 2017 в 19:40