英文:
replace the existing plot and not create a new one
问题
当用户输入 y 值时,我希望虚线图绘制在相同的现有图上,而不是创建一个新图。但它正在创建一个新图。有人能告诉我如何更新现有的图吗?以下是代码:
import matplotlib.pyplot as plt
# 现有的图
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'b-') # 示例图
# 显示图
plt.show()
# 请求用户输入
y_value = float(input("输入虚线的 y 值:"))
# 将用户输入的虚线添加到图上
plt.axhline(y=y_value, color='r', linestyle='--')
# 显示更新后的图
plt.show()
我尝试过 plt.clf()
,但没有起作用。
英文:
When the user input y value, I want the dashed line to be plotted on the same existing plot and not create a new plot. But it is creating a new plot. Could anyone please tell me how to update the existing plot. Below is the code
import matplotlib.pyplot as plt
# Existing plot
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'b-') # Example plot
# Display the plot
plt.show()
# Ask for user input
y_value = float(input("Enter the y-value for the line: "))
# Add the user input line to the plot
plt.axhline(y=y_value, color='r', linestyle='--')
# Display the updated plot
plt.show()
I tried to plt.clf()
, but it did not work.
答案1
得分: 1
以下是翻译好的部分:
# 首个答案,用于普通的Python脚本
(请查看末尾的更新,以了解在笔记本中的相同情况)
更简单的方法,从您的代码开始:使用`plt.pause(0.1)`,而不是`plt.show()`
```python
import matplotlib.pyplot as plt
plt.plot([1,2,3,4],[1,4,3,7])
plt.pause(0.1)
y=int(input("y值>"))
plt.axhline(y)
plt.show()
但您可能还想了解以下内容:
- plt.ion()
- animate()
- 使用setdata更新数据
plt.clf()
用于清除图形。与您所要求的交互式用法唯一相关的是,现在您知道如何向图形中添加一些新内容,您可能还需要删除一些内容。clf
会移除所有内容。这为您提供了"穷人动画"的方法,即绘制、使用pause
显示而不是使用show
,然后清除绘图,再次绘制。
更新:Jupyter笔记本
对于笔记本,您需要告诉Matplotlib您正在使用笔记本,以便它可以创建一种类似于常规窗口的JavaScript "窗口",并且您需要手动强制绘制,因为它不总是有效(有时,没有显式绘制,您会得到所有绘图都在同一张图中的结果,就像您想要的那样,但只有在单元格完成时才会出现这种情况,即最终结果)
import matplotlib
import matplotlib.pyplot as plt
%matplotlib notebook
fig=plt.figure()
plt.plot([1,2,3,4],[1,4,3,7])
fig.canvas.draw()
plt.pause(0.1)
y=int(input("y值>"))
plt.axhline(y)
plt.show()
请注意,您可以仅使用重绘而无需暂停。但由于它取决于Jupyter的版本、Matplotlib的版本、上下文等等,对于此类情况,我习惯于采用"裤子和背带"的方法。无论如何,draw
如果没有用处也不会造成问题,pause
也一样(除了丢失100毫秒,但由于它正好在人机交互之前,而且即使有这个暂停,人机交互仍然是交互中最慢的部分,所以这并不重要。此外,您也可以使用0.01,如果您更喜欢的话)。就目前而言,此代码在我所有的计算机上都有效——更重要的是,在我所有的学生计算机上都有效,包括笔记本。它还可以作为Python脚本(没有笔记本)运行,但需要%matplotlib notebook
声明。
<details>
<summary>英文:</summary>
# First answer, for regular python script
(see my update at the end for same in notebook)
The simpler method, starting from your code: use `plt.pause(0.1)`, not `plt.show()`
```python
import matplotlib.pyplot as plt
plt.plot([1,2,3,4],[1,4,3,7])
plt.pause(0.1)
y=int(input("y>"))
plt.axhline(y)
plt.show()
But you may also want to read about
- plt.ion()
- animate()
- updating data with setdata
plt.clf()
is to clear the figure. The only relation with the interactive usage you are asking for, is that, now that you know how to add some new things to your plot, you may need to remove things also. clf
removes everything. Giving you the "poor man animation" method, that is ploting, showing with pause
rather than with show
, and then clear the plot, and plot again.
Update : jupyter notebook
For notebook, you need to tell matplotlib that you are using a notebook, so that it can create a kind of javascript "window" to behaves almost as a normal window.
And you need to force the draw manually, since it doesn't always work (sometimes, without explicit draw, you end with all the plot in the same figure, as you want, but only when the cell is finished, that the final result)
import matplotlib
import matplotlib.pyplot as plt
%matplotlib notebook
fig=plt.figure()
plt.plot([1,2,3,4],[1,4,3,7])
fig.canvas.draw()
plt.pause(0.1)
y=int(input("y>"))
plt.axhline(y)
plt.show()
Note that you could do with only the redraw, and no pause. But because it depends on the version of jupyter, of matplotlib, on the context, etc., I am used to "belt and suspenders" approach for this kind of things. Any way, the draw
cannot harm if it is useless, neither does the pause
(but for the 100 ms lost, but since it is just before a human interaction, and human is the slowest part of the interaction even with this pause, it doesn't really matter. Besides, you can use 0.01 if you prefer). As is, this code works on all my computers — and more importantly on all my students computers with notebooks. And it also works as a python script (no notebook), but for the %matplotlib notebook
declaration
答案2
得分: 0
为了确保不创建新的图表,您可以使用“显式”API并调用plt.subplots
,它会提供一个您可以用来绘图的图和坐标轴对象。如果您使用这些,您将确保将图形添加到原始图表上。请注意:您可以使用“隐式”API,使用fig = plt.figure()
和ax = fig.gca()
,但我认为“显式”表述更清晰。
由于您很可能希望在用户输入要绘制的y值之前显示图表,您可以使用plt.pause(0.01)
,如@chrslg所建议。根据plt.pause
的文档:
> 如果有活动图形,它将在暂停之前更新和显示,而GUI事件循环(如果有的话)将在暂停期间运行。
import matplotlib.pyplot as plt
plt.close("all")
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 9, 16], "b-")
# 立即显示当前图表
plt.pause(0.01)
# 添加到先前的图表,因为我们现在正在告诉它要使用ax绘制到哪里
y_value = float(input("输入要绘制的y值:"))
ax.axhline(y=y_value, color="r", linestyle="--")
fig.show()
再强调一遍:通过使用Axes对象进行绘制,您确保更新适当的图表,而不是创建新的图表。
英文:
To make sure a new plot isn't created, you can make use of the "explicit" API and call plt.subplots
, which gives you a Figure and Axes object you can use to plot with. If you make use of those, you will ensure you're adding to the original plot. Note: this is possible using the "implicit" API using fig = plt.figure()
and ax = fig.gca()
, but I think the "explicit" formulation is clearer.
Since you most likely want the plot to be shown before the user inputs the y value to draw at, you can use plt.pause(0.01)
, as @chrslg suggests. According to the documentation of plt.pause
,
> If there is an active figure, it will be updated and displayed before the pause, and the GUI event loop (if any) will run during the pause.
import matplotlib.pyplot as plt
plt.close("all")
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 9, 16], "b-")
# display the current plot immediately
plt.pause(0.01)
# add to earlier plot because we are now telling it which to draw to using ax
y_value = float(input("Enter the y-value for the line: "))
ax.axhline(y=y_value, color="r", linestyle="--")
fig.show()
To reiterate: by making use of the Axes object to plot, you ensure the proper plot is updated rather than creating a new one.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论