缩放时保持绘图内的线标签可见
Keep line labels within plot visible when zooming
我正在使用 matplotlibs plt.axvline 在图表上绘制垂直线。我想将垂直线上的标签直接放在图表上,而不是图例中。
我希望我的图表在垂直线上具有如下所示的标签:
如果我放大某个部分,我希望垂直线标签相应地移动,以便它们在屏幕上仍然可见。像这样:
谁能帮我解决这个问题?将不胜感激!
到目前为止我的代码如下:
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)
]
文本标签默认位于 data-coordinates 中,这可能是您遇到的问题。您可以将 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 轴正确移动,但仍位于图的一半和四分之一处:
我正在使用 matplotlibs plt.axvline 在图表上绘制垂直线。我想将垂直线上的标签直接放在图表上,而不是图例中。
我希望我的图表在垂直线上具有如下所示的标签:
如果我放大某个部分,我希望垂直线标签相应地移动,以便它们在屏幕上仍然可见。像这样:
谁能帮我解决这个问题?将不胜感激!
到目前为止我的代码如下:
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)
]
文本标签默认位于 data-coordinates 中,这可能是您遇到的问题。您可以将 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 轴正确移动,但仍位于图的一半和四分之一处: