[英]Prevent labels from overlapping in matplotlib vertical timeline plot
我通常用於防止數據標簽重疊的方法似乎不適用於這個基於 matplotlib 的垂直時間線。 通常我會使用類似autofmt_xdate
的東西。
我實際上並不關心圖表需要有多“高”(長),或者項目之間的垂直距離是否完美地保留了項目之間的日期差距的比率。 我只是不希望文本標簽重疊。
我對matplotlib
不是很有經驗,但到目前為止我已經確定控制文本標簽的代碼是
_ = ax.text(label_offsets[i], d, l, ha=align, fontfamily='serif', fontweight='bold', color='royalblue',fontsize=12)
其中d
是用作 y 軸坐標的時間戳。 我嘗試創建一個循環計數器和一個列表以包含每次循環迭代中的d
值,以便我可以在當前日期和前一個日期之間進行比較,然后將一個固定值(例如 15 天)添加到d
的當前值如果d
的先前值太接近。 這似乎沒有奏效。
plot 代碼:
chartdata = pd.read_csv(
"data/Events.csv"
)
chartdata = chartdata.query('Year > 1939')
dates = pd.to_datetime(chartdata['Date_Clean_Approx'])
min_date = date(np.min(dates).year - 2, np.min(dates).month, np.min(dates).day)
max_date = date(np.max(dates).year + 2, np.max(dates).month, np.max(dates).day)
labels = chartdata['Name']
# labels with associated dates
labels = ['{0:%d %b %Y}:\n{1}'.format(d, l) for l, d in zip (labels, dates)]
fig, ax = plt.subplots(figsize=(6, 32), constrained_layout=True)
_ = ax.set_xlim(-20, 20)
_ = ax.set_ylim(min_date, max_date)
_ = ax.axvline(0, ymin=0.05, ymax=0.95, c='deeppink', zorder=1)
_ = ax.scatter(np.zeros(len(dates)), dates, s=120, c='palevioletred', zorder=2)
_ = ax.scatter(np.zeros(len(dates)), dates, s=30, c='darkmagenta', zorder=3)
label_offsets = np.repeat(2.0, len(dates))
label_offsets[1::2] = -2.0
for i, (l, d) in enumerate(zip(labels, dates)):
d = d - timedelta(days=90)
align = 'right'
if i % 2 == 0:
align = 'left'
_ = ax.text(label_offsets[i], d, l, ha=align, fontfamily='serif', fontweight='bold', color='royalblue',fontsize=12)
stems = np.repeat(2.0, len(dates))
stems[1::2] *= -1.0
x = ax.hlines(dates, 0, stems, color='darkmagenta')
# hide lines around chart
for spine in ["left", "top", "right", "bottom"]:
_ = ax.spines[spine].set_visible(False)
# hide tick labels
_ = ax.set_xticks([])
_ = ax.set_yticks([])
_ = ax.set_title('UAP (UFO) Milestones, 1940 - Present',
fontweight="bold",
fontfamily='serif',
fontsize=16,
color='royalblue')
pyplot(fig)
正如您在圖片中看到的,我增加了 plot 的高度以減少標簽中的重疊。 plot 變得很長,但在文本中仍有重疊。 Once a solution is determined I think that embedding the logic to "adjust relative gap size and chart height as needed to avoid text label overlap" into a convenient plot function would be a large contribution to the matplotlib
library.
我絕對願意接受更好、更程序化的解決方案,但現在我用相同長度的連續整數向量替換了日期,並用它代替了除標簽文本之外的任何地方的實際日期。
###### Timeline#
chartdata = pd.read_csv(
"/home/kodachi/Documents/ET/aliendb/www/app/data/Events.csv"
)
chartdata=chartdata.query('Year > 1939')
dates = pd.to_datetime(chartdata['Date_Clean_Approx'])
min_date = date(np.min(dates).year - 2, np.min(dates).month, np.min(dates).day)
max_date = date(np.max(dates).year + 2, np.max(dates).month, np.max(dates).day)
###
# fake date
fake_d=np.c_[1:len(dates)]
###
labels = chartdata['Name']
# labels with associated dates
labels = ['{0:%d %b %Y}:\n{1}'.format(d, l) for l, d in zip (labels, dates)]
fig, ax = plt.subplots(figsize=(8, 28))#, constrained_layout=True)
_ = ax.set_xlim(-20, 20)
#_ = ax.set_ylim(min_date, max_date)
_ = ax.set_ylim(1, 96)
_ = ax.axvline(0, ymin=0.05, ymax=.985, c='deeppink', zorder=1)#ymax=0.95
#_ = ax.scatter(np.zeros(len(dates)), dates, s=120, c='palevioletred', zorder=2)
#_ = ax.scatter(np.zeros(len(dates)), dates, s=30, c='darkmagenta', zorder=3)
_ = ax.scatter(np.zeros(len(fake_d)), fake_d, s=120, c='palevioletred', zorder=2)
_ = ax.scatter(np.zeros(len(fake_d)), fake_d, s=30, c='darkmagenta', zorder=3)
#label_offsets = np.repeat(2.0, len(dates))
label_offsets = np.repeat(2.0, len(fake_d))
label_offsets[1::2] = -2.0
for i, (l, d) in enumerate(zip(labels, fake_d)): #dates
#d = d - timedelta(days=90)
align = 'right'
if i % 2 == 0:
align = 'left'
_ = ax.text(label_offsets[i], d, l, ha=align, fontfamily='serif',
fontweight='bold', color='royalblue',fontsize=12)
#stems = np.repeat(2.0, len(dates))
stems = np.repeat(2.0, len(fake_d))
stems[1::2] *= -1.0
#x = ax.hlines(dates, 0, stems, color='darkmagenta')
x = ax.hlines(fake_d, 0, stems, color='darkmagenta')
# hide lines around chart
for spine in ["left", "top", "right", "bottom"]:
_ = ax.spines[spine].set_visible(False)
# hide tick labels
_ = ax.set_xticks([])
_ = ax.set_yticks([])
_ = ax.set_title('UAP (UFO) Milestones, 1940 - Present',
fontweight="bold",
fontfamily='serif',
fontsize=16,
color='darkgreen')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.