简体   繁体   English

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

[英]How do I create a graph that has a continuous axes with matplotlib?

I'm trying to create an interactive graphs. 我正在尝试创建交互式图形。 I can't figure out how to plot a quadratic graph that is continuous - as in if you zoom out/move across the axes, the equation is plotted there, not just between 2 x points, so it's continuous. 我无法弄清楚如何绘制一个连续的二次图-就像在轴上缩小/移动一样,方程式在那里绘制,而不仅仅是在2个点之间,所以它是连续的。

I've got this so far. 到目前为止,我已经知道了。

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()

Matplotlib is does not plot functions, but rather points. Matplotlib不是绘制函数,而是指向。 Of course any continuous function can be approximated by points if they are only dense enough. 当然,如果连续函数仅足够密集,则可以用点近似。

The problem indeed occurs when zooming into the plot, in which case formerly dense points will spread out and a polygonial structure will be observable. 放大图时确实会发生问题,在这种情况下,以前的密集点将散布开,并且可以观察到多边形结构。 Inversely when zooming out, it may happen that the function has not been evaluated outside a specific range and hence the plot will stay mostly empty. 相反,缩小时,可能未在特定范围之外评估函数,因此该图将大部分保持空白。

A solution is to evaluate the function each time the axis limits change, notably on a grid which covers the complete axis range and has as many points as there are pixels. 一种解决方案是在每次轴限制更改时评估功能,尤其是在覆盖整个轴范围并且具有与像素一样多的点的网格上。 We can find out the number of pixels from the figure size and dpi. 我们可以从图形尺寸和dpi找出像素数。

To show the effect, I added a sinusodial function with a low amplitude here. 为了显示效果,我在这里添加了一个幅度较小的正弦函数。

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()

在此处输入图片说明

continuity is hard to replicate, it sounds like what you need is to increase the plot density. 连续性很难复制,听起来您需要的是增加绘图密度。 Change your loop and use numpy 更改循环并使用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()

If I understand your question, you want to dynamically recalculate the content of the plot (the coordinates) based on the current axis pan / zoom. 如果我理解您的问题,则希望基于当前轴的平移/缩放动态地重新计算绘图的内容(坐标)。 Doing so requires using event handling to detect a change in axis limits, then recalculate the coordinates with a predefined number of points between these limits, and finally updating the plot accordingly 这样做需要使用事件处理来检测轴极限的变化,然后使用这些极限之间的预定义数量的点重新计算坐标,最后相应地更新图

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()

Credits go to @ImportanceOfBeingErnest for showing how to connect an event handler on changes to the axes limits in this answer 致谢@ImportanceOfBeingErnest,以显示如何在此答案中更改轴限制时连接事件处理程序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM