如何使用matplotlib创建具有连续轴的图形?

4

我正在尝试创建交互式图表。我无法弄清如何绘制连续的二次图形 - 即如果您缩小/移动轴,方程将在那里绘制,而不仅仅是在2个x点之间,因此它是连续的。

到目前为止,我已经做到了这一点。

import matplotlib.pyplot as plt

xcoord=[]
ycoord=[]

for x in range(0,10):
    y=(2*x)**2 + 2*x + 4
    xcoord.append(x)
    ycoord.append(y)

plt.plot(xcoord,ycoord)
plt.show()
3个回答

4

Matplotlib不绘制函数,而是绘制点。当然,如果这些点足够密集,任何连续的函数都可以近似表示。

问题确实出现在缩放图形时,因为以前密集的点将会分散开来,形成多边形结构。相反地,在缩小图形时,可能会发生函数未在特定范围内进行评估,因此图形将大部分保持为空白。

解决方法是每次轴限制更改时计算函数值,特别是在覆盖完整轴范围且具有与像素数量相同的点的网格上。我们可以从图形大小和dpi中找到像素数。

为了展示效果,在这里添加了一个低振幅的正弦函数。

import numpy as np
import matplotlib.pyplot as plt

func = lambda x: (2*x)**2 + 2*x + -4 + 0.2*np.sin(x*20)

fig, ax = plt.subplots()
ax.axis([-8,8,-100,400])
line, = ax.plot([])

def update(evt=None):
    xmin,xmax = ax.get_xlim()
    npoints = fig.get_size_inches()[0]*fig.dpi
    x = np.linspace(xmin, xmax, npoints)
    y = func(x)
    line.set_data(x,y)
    fig.canvas.draw_idle()

ax.callbacks.connect('xlim_changed', update)    
fig.canvas.mpl_connect("resize_event", update)
plt.show()

enter image description here


1
如果我理解你的问题,你想根据当前轴的平移/缩放动态重新计算图形的内容(坐标)。这需要使用事件处理来检测轴限制的变化,然后使用这些限制之间预定义数量的点重新计算坐标,最后相应地更新图形。
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np


def my_func(x):
    return (2 * x) ** 2 + 2 * x + 4


def on_lims_change(axes):
    xmin, xmax = axes.get_xlim()
    new_x = np.linspace(xmin, xmax, 1000)
    new_y = my_func(new_x)
    l.set_data(new_x, new_y)


fig, ax = plt.subplots()
xcoord = np.linspace(0, 10, 1000)
ycoord = my_func(xcoord)
l, = ax.plot(xcoord, ycoord, 'r-')

ax.callbacks.connect('xlim_changed', on_lims_change)
ax.callbacks.connect('ylim_changed', on_lims_change)

on_lims_change(ax)
plt.show()

感谢 @ImportanceOfBeingErnest 指导了如何在坐标轴限制改变时连接事件处理程序 (参见此答案)


0

连续性很难复制,听起来你需要增加情节密度。更改您的循环并使用numpy

import numpy as np
numpy.linspace
import matplotlib.pyplot as plt

xcoord=[]
ycoord=[]

for x in np.linspace(0,10,1000):
    y=(2*x)**2 + 2*x + 4
    xcoord.append(x)
    ycoord.append(y)

plt.plot(xcoord,ycoord)
plt.show()

如果使用numpy,就不需要循环。xcoord=np.linspace(0,10,1000)ycoord=(2*xcoord)**2 + 2*xcoord + 4就足够了。 - Diziet Asahi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接