不同比例尺的叠加图
- 2025-03-20 08:46:00
- admin 原创
- 32
问题描述:
到目前为止我有以下代码:
colors = ('k','r','b')
ax = []
for i in range(3):
ax.append(plt.axes())
plt.plot(datamatrix[:,0],datamatrix[:,i],colors[i]+'o')
ax[i].set(autoscale_on=True)
对于每个轴的选项autoscale_on=True
,我认为每个图都应该有自己的 y 轴限制,但它们似乎都共享相同的值(即使它们共享不同的轴)。我如何将它们设置为比例以显示每个的范围datamatrix[:,i]
(只需显式调用.set_ylim()
?)此外,我如何为datamatrix[:,2]
上面可能需要的第三个变量()创建偏移 y 轴?谢谢大家。
解决方案 1:
听起来你想要的是子情节......你现在所做的没有多大意义(或者无论如何我对你的代码片段感到非常困惑......)。
尝试一些更像这样的事情:
import matplotlib.pyplot as plt
import numpy as np
fig, axes = plt.subplots(nrows=3)
colors = ('k', 'r', 'b')
for ax, color in zip(axes, colors):
data = np.random.random(1) * np.random.random(10)
ax.plot(data, marker='o', linestyle='none', color=color)
plt.show()
编辑:
如果您不想要子图,您的代码片段会更有意义。
您正在尝试将三个轴添加到彼此的正上方。Matplotlib 识别出图中已经有一个大小和位置完全相同的子图,因此它每次都返回相同的轴对象。换句话说,如果您查看列表ax
,您会发现它们都是同一个对象。
如果你真的想这样做,每次添加轴时都需要重置fig._seen
为空字典。不过,你可能并不想这样做。
不要将三个独立的图相互叠加,而是尝试使用twinx
。
例如
import matplotlib.pyplot as plt
import numpy as np
# To make things reproducible...
np.random.seed(1977)
fig, ax = plt.subplots()
# Twin the x-axis twice to make independent y-axes.
axes = [ax, ax.twinx(), ax.twinx()]
# Make some space on the right side for the extra y-axis.
fig.subplots_adjust(right=0.75)
# Move the last y-axis spine over to the right by 20% of the width of the axes
axes[-1].spines['right'].set_position(('axes', 1.2))
# To make the border of the right-most axis visible, we need to turn the frame
# on. This hides the other plots, however, so we need to turn its fill off.
axes[-1].set_frame_on(True)
axes[-1].patch.set_visible(False)
# And finally we get to plot things...
colors = ('Green', 'Red', 'Blue')
for ax, color in zip(axes, colors):
data = np.random.random(1) * np.random.random(10)
ax.plot(data, marker='o', linestyle='none', color=color)
ax.set_ylabel('%s Thing' % color, color=color)
ax.tick_params(axis='y', colors=color)
axes[0].set_xlabel('X-axis')
plt.show()
解决方案 2:
使用@joe-kington 的答案
快速引导某些内容以绘制共享 x 轴的多个 y 轴的图表:
# d = Pandas Dataframe,
# ys = [ [cols in the same y], [cols in the same y], [cols in the same y], .. ]
def chart(d,ys):
from itertools import cycle
fig, ax = plt.subplots()
axes = [ax]
for y in ys[1:]:
# Twin the x-axis twice to make independent y-axes.
axes.append(ax.twinx())
extra_ys = len(axes[2:])
# Make some space on the right side for the extra y-axes.
if extra_ys>0:
temp = 0.85
if extra_ys<=2:
temp = 0.75
elif extra_ys<=4:
temp = 0.6
if extra_ys>5:
print 'you are being ridiculous'
fig.subplots_adjust(right=temp)
right_additive = (0.98-temp)/float(extra_ys)
# Move the last y-axis spine over to the right by x% of the width of the axes
i = 1.
for ax in axes[2:]:
ax.spines['right'].set_position(('axes', 1.+right_additive*i))
ax.set_frame_on(True)
ax.patch.set_visible(False)
ax.yaxis.set_major_formatter(matplotlib.ticker.OldScalarFormatter())
i +=1.
# To make the border of the right-most axis visible, we need to turn the frame
# on. This hides the other plots, however, so we need to turn its fill off.
cols = []
lines = []
line_styles = cycle(['-','-','-', '--', '-.', ':', '.', ',', 'o', 'v', '^', '<', '>',
'1', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd', '|', '_'])
colors = cycle(matplotlib.rcParams['axes.color_cycle'])
for ax,y in zip(axes,ys):
ls=line_styles.next()
if len(y)==1:
col = y[0]
cols.append(col)
color = colors.next()
lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color))
ax.set_ylabel(col,color=color)
#ax.tick_params(axis='y', colors=color)
ax.spines['right'].set_color(color)
else:
for col in y:
color = colors.next()
lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color))
cols.append(col)
ax.set_ylabel(', '.join(y))
#ax.tick_params(axis='y')
axes[0].set_xlabel(d.index.name)
lns = lines[0]
for l in lines[1:]:
lns +=l
labs = [l.get_label() for l in lns]
axes[0].legend(lns, labs, loc=0)
plt.show()
解决方案 3:
感谢 Joe Kington 的回答,我可以想出一个解决方案来满足我的要求,即所有额外的 y 轴都位于图表的左侧。
我仍然想知道如何正确地做到这一点,因为这只是一个解决方法:
import matplotlib.pyplot as plt
import numpy as np
# To make things reproducible...
np.random.seed(1977)
fig, ax = plt.subplots()
# Twin the x-axis twice to make independent y-axes.
axes = [ax, ax.twinx(), ax.twinx()]
# Make some space on the right side for the extra y-axis.
fig.subplots_adjust(right=0.75)
# Move the last y-axis spine over to the right by 20% of the width of the axes
axes[1].spines['right'].set_position(('axes', -0.25))
axes[2].spines['right'].set_position(('axes', -0.5))
# To make the border of the right-most axis visible, we need to turn the frame
# on. This hides the other plots, however, so we need to turn its fill off.
axes[-1].set_frame_on(True)
axes[-1].patch.set_visible(False)
# And finally we get to plot things...
colors = ('Green', 'Red', 'Blue')
intAxNo = 0
for ax, color in zip(axes, colors):
intAxNo += 1
data = np.random.random(1) * np.random.random(10)
ax.plot(data, marker='o', linestyle='none', color=color)
if (intAxNo > 1):
if (intAxNo == 2):
ax.set_ylabel('%s Thing' % color, color=color, labelpad = -40 )
elif (intAxNo == 3):
ax.set_ylabel('%s Thing' % color, color=color, labelpad = -45 )
ax.get_yaxis().set_tick_params(direction='out')
else:
ax.set_ylabel('%s Thing' % color, color=color, labelpad = +0 )
ax.tick_params(axis='y', colors=color)
axes[0].set_xlabel('X-axis')
plt.show()
解决方案 4:
twinx
.简短示例:
fig1 = matplotlib.figure.Figure() # Make a figure
ax1 = fig1.add_subplot() # Add the primary axis
ax1.plot([100, 300, 200]) # Plot something
ax2 = ax1.twinx() # Add the secondary axis
ax2.plot([5000, 2000, 6000]) # Plot something with a different scale
display( fig1 ) # Display it (Jupyter only)
解决方案 5:
我已经使用了这个代码,它成功地生成了两个 Y 轴(主轴和次轴),并具有从 Excel 文件中读取数据的所需比例:
X = df[['x-axis variable']]
Y1=df[['1st Y-Variable']]
Y2=df[['2nd Y-Variable']]
Y3=df[['3rd Y-Variable']]
fig, ax1 = plt.subplots(figsize=(10,6))
ax2 = ax1.twinx()
ax1.plot(X, Y1, 'g', label='Curve.1 name') #plotting on primary Y-axis
ax1.plot(X, Y2, 'm', label='Curve.2 name') #plotting on primary Y-axis
ax2.plot(X, wob, 'b', label='Curve.3 name') #plotting on **second** Y-axis
ax1.set_ylim(0, 350) #Define limit/scale for primary Y-axis
ax2.set_ylim(1000, 1300) #Define limit/scale for secondary Y-axis
plt.show()
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD