简体   繁体   English

Python Matplotlib对数自动缩放

[英]Python matplotlib logarithmic autoscale

I need to get ax,y plot with a logarithmic scale on the x-axes. 我需要在x轴上获得带有对数标度的ax,y图。 When I zoom in the x-axes should autoscale as the (not logarithmic) y-axes. 当我放大x轴时,应自动缩放(而不是对数)y轴。

plt.xscale('log')
plt.grid(True)
plt.autoscale(True,True,True)
plt.legend(loc='best')
plt.show()

正常打印

放大打印

As you can see there is no working autoscale function on the x-axes. 如您所见,x轴上没有可用的自动缩放功能。 How can I get this to display properly? 我怎样才能使其正确显示?

The solution by @hashcode55 does not work as it is what I was attempting before I found this thread. @ hashcode55的解决方案不起作用,因为这是我在找到此线程之前所尝试的解决方案。

It seems to me that there is simply a "bug" in that: 在我看来,其中仅存在一个“错误”:

plt.yscale('log')
plt.autoscale(enable=True, axis='y')

are not compatible. 不兼容。

Here is my sample code: 这是我的示例代码:

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

# generate some random data and add it to the plot
x = np.array(range(1,100))
y = np.maximum(np.ones(99), np.random.randn(99))
plt.plot(x, y, markersize=4, marker='.', color='red')

# format
ax = plt.gca()
plt.ylabel('LOGARITHMIC SCALE')
plt.yscale('log')
plt.minorticks_on
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
plt.autoscale(enable=True, axis='y')

#ax.set_ylim([np.min(y), np.max(y)])

#plot
plt.show()

which produces: 产生:

在此处输入图片说明

log scale, but clearly not autoscale 对数刻度,但显然不是自动刻度

if I remove the comments from this line: 如果我从这一行删除评论:

ax.set_ylim([np.min(y), np.max(y)])

Then it actually plots as would be expected with autoscale: 然后,它实际上会按照自动缩放的预期进行绘制:

在此处输入图片说明

Nice, but what if I've lost reference to my y values on the plot? 很好,但是如果我在情节上没有参考自己的y值怎么办?

while this solution/answer is a good "hack" to this sample problem, it its not a solid solution for my situation as my chart is a) live; 尽管此解决方案/答案是解决此示例问题的好方法,但对于我的情况,它并不是一个可靠的解决方案,因为我的图表是a)实时的; continually updating every minute b) contains MANY plots c) is dropping off data older than past 24 hours; b)每分钟持续更新b)包含许多图c)正在删除早于24小时的数据; so such a solution would get really hacky if implemented every time something was added or removed from the plot in live session. 因此,如果每次在实时会话中从情节中添加或删除某项内容时都实施该解决方案,那么该解决方案将变得非常笨拙。

I would be interested in a true built-in "autoscale" solution, if such exists, that works with log y scale and I can auto update using plt.ion() 我会对真正的内置“自动缩放”解决方案感兴趣,如果存在的话,该解决方案可以对数y缩放,并且我可以使用plt.ion()自动更新

until then, what about this: 在那之前,这是怎么回事:

h/t @David Z How to extract data from matplotlib plot h / t @David Z 如何从matplotlib图中提取数据

#if you do need to get data out of a plot, I think this should do it

gca().get_lines()[n].get_xydata()

#Alternatively you can get the x and y data sets separately:

line = gca().get_lines()[n]
xd = line.get_xdata()
yd = line.get_ydata()

implemented in our situation at hand (with an extra blue line to test multiple lines) as: 在我们当前的情况下实现(用一条额外的蓝线测试多条线)为:

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

# generate some random data and add it to the plot
x = np.array(range(1,100))
y = np.maximum(np.ones(99), np.random.randn(99))
plt.plot(x, y, markersize=4, marker='.', color='red')

# test for compatibility with multilpes lines
x = np.array(range(1,100))
y = np.maximum(np.ones(99), 1.5*np.random.randn(99))
plt.plot(x, y, markersize=4, marker='.', color='blue')

# format
ax = plt.gca()
plt.ylabel('LOGARITHMIC SCALE')
plt.yscale('log')
plt.minorticks_on
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
#plt.autoscale(enable=True, axis='y')

#####################################################
#force 'autoscale'
#####################################################
yd = [] #matrix of y values from all lines on plot
for n in range(len(plt.gca().get_lines())):
        line = plt.gca().get_lines()[n]
        yd.append(line.get_ydata())
ax.set_ylim([0.9*np.min(yd), 1.1*np.max(yd)])
#####################################################  

#plot
plt.show()

which, in essence, is pulling all y data from all lines on the plot, finding the max and min; 从本质上讲,这是从图中的所有线中提取所有y数据,从而找到最大值和最小值; then implementing them via set_ylim ; 然后通过set_ylim实现它们; "forcing" autoscale “强制”自动缩放

yields: 收益率:

在此处输入图片说明

voila! 瞧!

for my situation I had somewhat more complicated plots in the format: 对于我的情况,我的格式有些复杂:

plt.plot((x1,x2), (y1,y2))

creating a matrix in matrix situation producing a 'Value Error' 在矩阵情况下创建矩阵,产生“值错误”

for that I had to flatten using: 为此,我不得不使用:

yd = [item for sublist in yd for item in sublist]

h/t @Alex Martelli Making a flat list out of list of lists in Python h / t @Alex Martelli 用Python列出的清单制作一个平面清单

and this was the final product: 这是最终产品:

#####################################################
#force 'autoscale'
#####################################################
yd = [] #matrix of y values from all lines on plot
for n in range(len(plt.gca().get_lines())):
        line = plt.gca().get_lines()[n]
        yd.append((line.get_ydata()).tolist())

yd = [item for sublist in yd for item in sublist]
ax.set_ylim([0.9*np.min(yd), 1.1*np.max(yd)])
#####################################################

在此处输入图片说明

If you look at the documentation the function is like- 如果您查看文档,该功能类似于-

matplotlib.pyplot.autoscale(enable=True, axis='both', tight=None)

What you are sending is an invalid argument... 您发送的是无效的参数...

just make it 只要做到

plt.autoscale(True, axis = 'both')

And about tight - 而关于紧-

If True, set view limits to data limits; 如果为True,则将视图限制设置为数据限制。 if False, let the locator and margins expand the view limits; 如果为False,则使定位器和边距扩大视图范围; if None, use tight scaling if the only artist is an image, otherwise treat tight as False. 如果为None,则在唯一的艺术家是图像的情况下使用紧缩缩放,否则将紧缩视为False。 The tight setting is retained for future autoscaling until it is explicitly changed. 严格设置将保留以备将来自动缩放,直到明确更改为止。

I had a similar problem and I was able to solve it by setting the 'log' scale before plotting. 我有一个类似的问题,我可以通过在绘制之前设置“对数”比例来解决。 In this case, the autoscaling is working as expected. 在这种情况下,自动缩放功能将按预期工作。

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

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