在Matplotlib绘图上添加一个圆圈到特定日期。

huangapple go评论66阅读模式
英文:

Adding a circle on specific date in a matplotlib plot

问题

我使用以下代码创建了一个matplotlib绘图:

ax.plot(df_c.index, y1, color='b')

这里的df_c.index是一个DatetimeIndex

DatetimeIndex(['2019-10-31', '2019-11-01', '2019-11-02', '2019-11-03',
               '2019-11-04', '2019-11-05', '2019-11-06', '2019-11-07',
               '2019-11-08', '2019-11-09',
               ...
               '2020-04-04', '2020-04-05', '2020-04-06', '2020-04-07',
               '2020-04-08', '2020-04-09', '2020-04-10', '2020-04-11',
               '2020-04-12', '2020-04-13'],
              dtype='datetime64[ns]', length=166, freq=None)

上述代码创建了一个线图。

我想在日期'2020-04-12'上添加一个值为100的圆圈。我尝试了以下代码:

ax.plot(datetime.date(2020, 04, 12), 100, 'bo')

但它不起作用。我该如何修复它?

英文:

I have a matpltolib plot made using this code:

ax.plot(df_c.index, y1, color='b')

Here df_c.index is:

DatetimeIndex(['2019-10-31', '2019-11-01', '2019-11-02', '2019-11-03',
               '2019-11-04', '2019-11-05', '2019-11-06', '2019-11-07',
               '2019-11-08', '2019-11-09',
               ...
               '2020-04-04', '2020-04-05', '2020-04-06', '2020-04-07',
               '2020-04-08', '2020-04-09', '2020-04-10', '2020-04-11',
               '2020-04-12', '2020-04-13'],
              dtype='datetime64[ns]', length=166, freq=None)

The above code makes a lineplot.

I want to add a circle on this date '2020-04-12' with a value of 100. How do I do that? I tried:

ax.plot(datetime.date(2020, 04, 12), 100, 'bo')

but it does not work. How can I fix it?

答案1

得分: 4

我不确定您想在哪里绘制您的圆圈,但我在这里提供了三个不同的圆圈位置以及一个更简单的第四个备选项,只是为了突出显示特定日期。演示图像显示在底部。首先,让我们绘制一些数据:

import matplotlib.pyplot as plt

dates = ['2019-10-31', '2019-11-01', '2019-11-02', '2019-11-03']

y = [i*i for i in range(len(dates))] # 一些随机的y值

# 一个要圈起来的任意日期值
encircled_date = dates[1]
val_of_encircled_date = y[1]

# 绘制图表
fig, ax = plt.subplots()
ax.plot_date(dates, y, '-')
bottom, top = plt.ylim() # 后面,我们需要y轴最小值以正确定位圆圈

现在,如果您只想在图表上有一个圆圈,经过您指定的日期,最简单且(在我看来)最好的方法是只需重新绘制该特定值,但使用 markerstyle='o'。根据您的喜好调整标记大小、线宽和颜色:

# 在特定图表值周围绘制一个圆圈
ax.plot_date(encircled_date, val_of_encircled_date,
                    'og', # 标记样式 'o',颜色 'g'
                    fillstyle='none', # 圆圈不填充颜色
                    ms=10.0) # 标记/圆圈的大小

然后,如果您希望在x轴上的日期刻度周围有一个圆圈,用于指定日期,这会稍微复杂一些,具体取决于您需要圈起的细节。当然,您可以使用上面的方法仅获得刻度周围的小圆圈,但我将展示一种基于另一个SO问题的更高级方法:

# 在x轴上特定日期的‘刻度’周围绘制一个圆圈
circle1 = plt.Circle((encircled_date, bottom), # 位置
                    1.0 / len(dates), # 半径
                    color='r',
                    clip_on=False, # 允许在轴外绘制
                    fill=False)
ax.add_artist(circle1)

上述解决方案仅包围刻度,而不包括日期标签本身。我们可以微调圆圈以适应日期标签,通过调整两个偏移参数:

# 在x轴上特定日期的标签周围绘制一个圆圈
pos_offset = 0.5
len_offset = 0.4
circle2 = plt.Circle((encircled_date, bottom-pos_offset), # 位置
                    (1.0+len_offset) / len(dates), # 半径
                    color='purple',
                    clip_on=False, # 允许在轴外绘制
                    fill=False)
ax.add_artist(circle2)

然而,这种微调可能会是一项繁琐的任务。如果您的目标只是强调特定日期,最好的方法可能是简单地重新配置x标签。例如,您可以像这样更改标签的颜色:

ax.get_xticklabels()[2].set_color("red")
ax.get_xticklabels()[2].set_weight("bold")

这四种不同的方法显示在下面的图像中。希望这可以帮助您。

最后一句话: 当您获得一个日期密集的x轴时,可能值得研究更高级的日期标签格式化,您可以在官方文档中详细了解这方面的知识。例如,他们展示了如何将标签巧妙地旋转以使它们更接近而不重叠。

英文:

I'm not entirely certain where you want to draw your circle, but I present here three different circle positions, and a simpler fourth alternative just for highlighting a specific date. A demo image is shown at the bottom. First, let's just plot some data:

import matplotlib.pyplot as plt

dates = ['2019-10-31', '2019-11-01', '2019-11-02', '2019-11-03']

y = [i*i for i in range(len(dates))] # some random y values

# An arbitrary date value to encircle 
encircled_date = dates[1]
val_of_encircled_date = y[1]

# Plot the graph
fig, ax = plt.subplots()
ax.plot_date(dates,y,'-')
bottom, top = plt.ylim() # Later, we'll need the min value of the y-axis for correct positioning of circle

Now, if you just want a circle at the graph, as it passes through your specific date, the simplest and (imho) best approach is to simply replot that specific value, but with markerstyle='o'. Adjust marker size, line width and color to your preferences:

# Plot a circle around specific graph value
ax.plot_date(encircled_date, val_of_encircled_date,
                'og', # marker style 'o', color 'g'
                fillstyle='none', # circle is not filled (with color)
                ms=10.0) # size of marker/circle

Then, if you instead wanted a circle around the date-tick, on the x-axis for your specific date, it is a little more tricky depending on what details you need to encircle. Of course, you could use the approach above to get a small circle around the tick only, but I'll show a more advanced approach based on another SO-question:

# Plot a circle around the 'tick' of specific date on the x-axis
circle1 = plt.Circle((encircled_date, bottom), # position
                    1.0 / len(dates), # radius
                    color='r',
                    clip_on=False, # allow drawing outside of axes
                    fill=False)
ax.add_artist(circle1)

The above solution only encircles the tick, and not the date label itself. We may micro adjust the circle to fit the date-label inside, by tuning two offset parameters,

# Plot a circle around the specific date's label on the x-axis
pos_offset = 0.5
len_offset = 0.4
circle2 = plt.Circle((encircled_date, bottom-pos_offset), # position
                    (1.0+len_offset) / len(dates), # radius
                    color='purple',
                    clip_on=False, # allow drawing outside of axis
                    fill=False)
ax.add_artist(circle2)

However, this tuning may be a tedious task. If your objective is only to emphasize this particular date, it may be better to simply reconfigure the x-label. You may for instance change the color of the label like this,

ax.get_xticklabels()[2].set_color("red")
ax.get_xticklabels()[2].set_weight("bold")

The four different approaches are shown in the image below. I hope this helps.

One final remark: When you get a densely populated x-axis of dates, it might be worthwhile looking into more advanced formatting of date-labels which you can read all about in the official documentation. For instance, they show how to neatly rotate the labels to fit them closer together without overlapping.

在Matplotlib绘图上添加一个圆圈到特定日期。

huangapple
  • 本文由 发表于 2020年1月3日 14:35:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定