简体   繁体   English

使用set_xlim()切割绘图后的matplotlib自动缩放(axis ='y')

[英]matplotlib autoscale(axis='y') after slicing plot with set_xlim()

As a demonstration, I'm plotting x^0 through x^9 with x values in range from 10 to 20. 作为演示,我正在绘制x ^ 0到x ^ 9,x值在10到20之间。

Then I'm slicing those images so that I have 9 slices: 然后我正在切片那些图像,以便我有9个切片:

x = (10 to 11), (11 to 12) etc. to (18 to 19) x =(10到11),(11到12)等等到(18到19)

I want my images cropped so that y values are always spread from top to bottom in each slice, but what I'm getting is autoscale always scales to the full dataset rather than the current slice. 我希望我的图像被裁剪,以便y值始终在每个切片中从上到下展开,但我得到的是自动缩放始终缩放到完整数据集而不是当前切片。

import matplotlib.pyplot as plt
import numpy as np


# create some test data
for i in range(10):
    x = np.arange(10,20)
    y = x**i
    plt.plot(x,y,c='red',marker='.',ms=2)

# get all x values in chart and reduce to a sorted list set
xd = [] 
for n in range(len(plt.gca().get_lines())):
        line = plt.gca().get_lines()[n]
        xd.append((line.get_xdata()).tolist())
xd = [item for sublist in xd for item in sublist]
xd = sorted(list(set(xd)))

# attempt to plot slices of x with autoscaled y
ax = plt.gca()
for i in range(len(xd)-1):
    ax.set_xlim([xd[i],xd[i+1]])
    ax.axes.autoscale(enable=True,axis='y', tight=True)
    plt.pause(1) #timing
    #uncommenting the next line will create nine tiny (6kb) image files
    #plt.savefig(('image_%s.png' % i), bbox_inches=0, dpi=48)

In my actual application, I'm attempting to generate 100k tiny images in this manner as a database from stochastic data. 在我的实际应用中,我试图以这种方式生成10万个微小图像作为随机数据的数据库。 For every x there are between 2 and 200 y values. 对于每x,有2到200 y的值。 Then I'm using OpenCV to image match new images to the best fit amongst the historical database. 然后我使用OpenCV将新图像匹配到历史数据库中的最佳匹配。

Its critical that the y values are stretched from top to bottom in each image for OpenCV to find a good match. 关键是y值在每个图像中从上到下拉伸,以便OpenCV找到一个很好的匹配。

if it helps my x values will always be int() type and equally spaced 如果它有助于我的x值始终是int()类型和等间距

ETA: I've attempted to implement some of the solutions here but have made no progress: ETA:我试图在这里实施一些解决方案,但没有取得任何进展:

Matplotlib - fixing x axis scale and autoscale y axis Matplotlib - 固定x轴刻度和自动缩放y轴

Matplotlib scale y axis based on manually zoomed x axis Matplotlib基于手动缩放的x轴缩放y轴

but at least I've learned: 但至少我学会了:

Autoscaling always uses the full range of the data, so the y-axis is scaled by full extent of the y-data, not just what's within the x-limits. 自动缩放始终使用全范围的数据,因此y轴按y数据的完整范围进行缩放,而不仅仅是x限制内的范围。

still no solution that works here though 仍然没有解决方案在这里工作

def autoscale_y()

presented by @DanHickstein 由@DanHickstein提供

gives me: 给我:

h = np.max(y_displayed) - np.min(y_displayed)
ValueError: zero-size array to reduction operation maximum which has no identity

From those links, I'm unsure where to implement @Joe Kington's mask solution in my for loops. 从这些链接中,我不确定在我的for循环中在哪里实现@Joe Kington的掩码解决方案。

I'm now working with @bernie solution proposed here to get Y values given X: 我现在正在使用这里提出的@bernie解决方案来获得Y值:

How to extract points from a graph? 如何从图中提取点?

maybe then I can set_ylim() given the min and max Y values at that X manually? 也许那时我可以set_ylim()手动给出那个X的最小和最大Y值?

This would be so much easier if there was a way to autoscale within the defined xlim as a standard matplotlib method 如果有一种方法可以在定义的xlim中作为标准的matplotlib方法进行自动缩放,那么这将更加容易

I solved my issue last night by creating a dictionary with x's as keys and a respective list of y's as values. 我昨晚解决了我的问题,创建了一个字典,其中x为键,y为y值。

This occurs as the data is created by the function y=x**i 这是在数据由函数y = x ** i创建时发生的

in essence I'm creating dictionary structure pseudocode: 本质上我正在创建字典结构伪代码:

data[x0] = [x0y1,x0y2,x0y3....]
data[x1] = [x1y1,x1y2,x1y3....]
data[x2] = [x2y1,x2y2,x2y3....]
etc.

I can later reference all the y values at any given x. 我可以稍后在任何给定的x处引用所有y值。 From there, find the min and max y value for the left and right side of my slice to manually set ylim. 从那里,找到切片左侧和右侧的最小和最大y值,以手动设置ylim。 If your xlim slice was more than one x segment wide you'd have to repeat the process for each respective x slice within your xlim. 如果您的xlim切片超过一个x段宽,则必须为xlim中的每个相应x切片重复该过程。 In my instance, my x slices are exactly one segment wide. 在我的例子中,我的x切片恰好是一个段宽。

import matplotlib.pyplot as plt
import numpy as np

# move my range function out of my data creation loop
x = np.arange(10,20,1)

# create a dictionary of my data with x values as keys
data = {}
for i in range(len(x)):
   data[x[i]]=[]

# create some test data
for i in range(10):
    y = x**i
    plt.plot(x,y,c='red',marker='.',ms=2)

    # store my y data to my data dictionary as its created
    xx = x[-len(y):]
    for j in range(len(xx)):
        data[xx[j]].append(y[j])

# get all x values in chart and reduce to a sorted list set
xd = [] 
for n in range(len(plt.gca().get_lines())):
        line = plt.gca().get_lines()[n]
        xd.append((line.get_xdata()).tolist())
xd = [item for sublist in xd for item in sublist]
xd = sorted(list(set(xd)))

# attempt to plot slices of x with autoscaled y
ax = plt.gca()
for i in range(len(xd)-1):
    ax.set_xlim([xd[i],xd[i+1]])

    # reference my min and max y values by left and right borders of x slice
    ymin = min(min(data[xd[i]]), min(data[xd[i+1]]))
    ymax = max(max(data[xd[i]]), max(data[xd[i+1]]))
    # manually set y limits
    ax.set_ylim([ymin,ymax])

    #eliminate my autoscale call
    #ax.axes.autoscale(enable=True,axis='y', tight=True)
    plt.pause(1) #timing

Now when it plots, y is autoscaled to the x slice, not the entire dataset. 现在绘制时,y会自动缩放到x切片,而不是整个数据集。

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

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