我想只绘制数组的一部分,修复x部分,但让y部分自动缩放。我尝试如下所示,但它不起作用。
有什么建议吗?
import numpy as np
import matplotlib.pyplot as plt
data=[np.arange(0,101,1),300-0.1*np.arange(0,101,1)]
plt.figure()
plt.scatter(data[0], data[1])
plt.xlim([50,100])
plt.autoscale(enable=True, axis='y')
plt.show()
答案 0 :(得分:15)
虽然Joe Kington当他建议只绘制必要的数据时,肯定会提出最明智的答案,但有些情况下最好绘制所有数据并缩放到某个部分。另外,有一个" autoscale_y"仅需要轴对象的函数(即,与答案here不同,这需要直接使用数据。)
这是一个根据可见x区域中的数据重新缩放y轴的函数:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-100,100,1000)
y = x**2 + np.cos(x)*100
fig,axs = plt.subplots(1,2,figsize=(8,5))
for ax in axs:
ax.plot(x,y)
ax.plot(x,y*2)
ax.plot(x,y*10)
ax.set_xlim(-10,10)
autoscale_y(axs[1])
axs[0].set_title('Rescaled x-axis')
axs[1].set_title('Rescaled x-axis\nand used "autoscale_y"')
plt.show()
这是一种黑客攻击,在许多情况下可能不会起作用,但对于一个简单的情节,它运作良好。
以下是使用此功能的简单示例:
{{1}}
答案 1 :(得分:6)
自动缩放始终使用全部数据,因此y轴按y数据的全部范围缩放,而不仅仅是x限制内的范围。
如果您想显示数据的子集,那么仅绘制该子集可能最简单:
import numpy as np
import matplotlib.pyplot as plt
x, y = np.arange(0,101,1) ,300 - 0.1*np.arange(0,101,1)
mask = (x >= 50) & (x <= 100)
fig, ax = plt.subplots()
ax.scatter(x[mask], y[mask])
plt.show()
答案 2 :(得分:1)
pandas
,这使得使用 Boolean indexing 选择数据非常容易。x
和 y
加载到 DataFrame 中,将布尔选择与 pandas.Series.between(left, right, inclusive=True)
一起使用,并直接与使用 matplotlib
的 pandas.DataFrame.plot
一起绘制。import numpy as np # for the test data
import pandas as pd
# load the data into the dataframe; there are many ways to do this
df = pd.DataFrame({'x': np.arange(0,101,1), 'y': 300-0.1*np.arange(0,101,1)})
# select and plot the data
ax = df[df.x.between(50, 100)].plot(x='x', y='y', kind='scatter', figsize=(5, 4))
答案 3 :(得分:0)
我以@DanHickstein的答案为基础,以涵盖用于缩放x或y轴的绘图,散点图和axhline / axvline的情况。可以像在autoscale()
上一样在最新的轴上工作。如果您要编辑它,请fork it on gist。
def autoscale(ax=None, axis='y', margin=0.1):
'''Autoscales the x or y axis of a given matplotlib ax object
to fit the margins set by manually limits of the other axis,
with margins in fraction of the width of the plot
Defaults to current axes object if not specified.
'''
import matplotlib.pyplot as plt
import numpy as np
if ax is None:
ax = plt.gca()
newlow, newhigh = np.inf, -np.inf
for artist in ax.collections + ax.lines:
x,y = get_xy(artist)
if axis == 'y':
setlim = ax.set_ylim
lim = ax.get_xlim()
fixed, dependent = x, y
else:
setlim = ax.set_xlim
lim = ax.get_ylim()
fixed, dependent = y, x
low, high = calculate_new_limit(fixed, dependent, lim)
newlow = low if low < newlow else newlow
newhigh = high if high > newhigh else newhigh
margin = margin*(newhigh - newlow)
setlim(newlow-margin, newhigh+margin)
def calculate_new_limit(fixed, dependent, limit):
'''Calculates the min/max of the dependent axis given
a fixed axis with limits
'''
if len(fixed) > 2:
mask = (fixed>limit[0]) & (fixed < limit[1])
window = dependent[mask]
low, high = window.min(), window.max()
else:
low = dependent[0]
high = dependent[-1]
if low == 0.0 and high == 1.0:
# This is a axhline in the autoscale direction
low = np.inf
high = -np.inf
return low, high
def get_xy(artist):
'''Gets the xy coordinates of a given artist
'''
if "Collection" in str(artist):
x, y = artist.get_offsets().T
elif "Line" in str(artist):
x, y = artist.get_xdata(), artist.get_ydata()
else:
raise ValueError("This type of object isn't implemented yet")
return x, y
像它的前一个一样,它有点笨拙,但这是必需的,因为集合和行具有不同的返回xy坐标的方法,并且因为axhline / axvline很难处理,因为它只有两个数据点。
这里正在起作用:
fig, axes = plt.subplots(ncols = 4, figsize=(12,3))
(ax1, ax2, ax3, ax4) = axes
x = np.linspace(0,100,300)
noise = np.random.normal(scale=0.1, size=x.shape)
y = 2*x + 3 + noise
for ax in axes:
ax.plot(x, y)
ax.scatter(x,y, color='red')
ax.axhline(50., ls='--', color='green')
for ax in axes[1:]:
ax.set_xlim(20,21)
ax.set_ylim(40,45)
autoscale(ax3, 'y', margin=0.1)
autoscale(ax4, 'x', margin=0.1)
ax1.set_title('Raw data')
ax2.set_title('Specificed limits')
ax3.set_title('Autoscale y')
ax4.set_title('Autoscale x')
plt.tight_layout()
答案 4 :(得分:0)
我想补充@TomNorway的一个很好的答案(这节省了我很多时间),以处理某些艺术家完全由NaN组成的情况。
我所做的所有更改都在
内部=sum(
query(I10:I19,"select count(I) where I matches" & Regex!A1 & "label count(I) ''"),
query(J10:J19,"select count(J) where J matches" & Regex!A1 & "label count(J) ''"),
query(K10:K19,"select count(K) where K matches" & Regex!A1 & "label count(K) ''"),
[etc. etc.]
)
干杯!
if len(fixed) > 2: