猿问

条形图(主要)然后折线图(次要)工作正常,但如果我更改代码中的顺序则不起作用

我需要将这两个图放在一起,但是当我使用条形图(主要)然后使用折线图(次要)时,它工作得很好。如果我改变关于情节的代码行中的顺序,它就不起作用。


import matplotlib.pyplot as plt

import numpy as np

import pandas as pd


flatui1 = ["#0C6514", "#18AB25"]

flatui2 = ["#0E1D56", "#18AB25"]

colors = sns.color_palette(flatui1)

cmap1 = LinearSegmentedColormap.from_list("my_colormap", colors)

colors = sns.color_palette(flatui2)

cmap2 = LinearSegmentedColormap.from_list("my_colormap", colors)

sns.set_style(style='whitegrid')


m1_t = pd.DataFrame({

    "A":[0.21,0.05,1.22,0.41,1.28,1.15,0.91,0.63,0.38,1.18],

    "B":[13.33,18,23.69,21.46,35.31,16,20.11,15.87,20.53,17.71],

    "C":[5.71,2,23.44,9.02,35.39,13.48,14.62,13.17,13.68,14.66]

})


# This two line sequence has the problem

m1_t['A'].plot(kind='bar',colormap=cmap1)

m1_t[['B','C']].plot(kind='line',secondary_y=True,colormap=cmap2)



ax = plt.gca()

ax.grid(True)

ax.set_axisbelow(True)

ax.set_xticklabels(('P0', 'P1','P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9'))

plt.savefig('Comparison',dpi=300)

plt.show()


https://i.stack.imgur.com/I9yXy.png


翻阅古今
浏览 89回答 2
2回答

饮歌长啸

绘制此图的更好方法是使用面向对象的 matplotlib api。首先,我们必须定义我们的Figure,axes然后为了正确绘制第二个 y,我们将创建一个伪轴对象,该对象链接回我们创建的原始轴。然后我们可以告诉 pandas 直接在我们的轴上绘图,以确保所有内容都到达正确的位置。import matplotlib.pyplot as pltfrom matplotlib.colors import LinearSegmentedColormapimport numpy as npimport pandas as pdimport seaborn as snsflatui1 = ["#0C6514", "#18AB25"]flatui2 = ["#0E1D56", "#18AB25"]colors = sns.color_palette(flatui1)cmap1 = LinearSegmentedColormap.from_list("my_colormap", colors)colors = sns.color_palette(flatui2)cmap2 = LinearSegmentedColormap.from_list("my_colormap", colors)sns.set_style(style='white') # we don't want the grid coming from seabornm1_t = pd.DataFrame({    "A":[0.21,0.05,1.22,0.41,1.28,1.15,0.91,0.63,0.38,1.18],    "B":[13.33,18,23.69,21.46,35.31,16,20.11,15.87,20.53,17.71],    "C":[5.71,2,23.44,9.02,35.39,13.48,14.62,13.17,13.68,14.66]})fig, ax = plt.subplots()twin_x = ax.twinx() # Create a pseudo axes based off of the original# ax is our main plot with the "primary y-axis"# twin_x is also our main plot, but plotting on this plots#   our "secondary y" axis# Put the bar plot on the "primary y" via ax=axm1_t['A'].plot(kind='bar',colormap=cmap1, ax=ax, zorder=1)# Put the line plot on the "secondary y" via ax=twin_x#  don't have pandas place our legend by default, we'll do this manually for more control laterm1_t[['B','C']].plot(kind='line', colormap=cmap2, ax=twin_x, zorder=2, legend=False)ax.grid(True, zorder=0)ax.set_axisbelow(True)ax.set_xticklabels(('P0', 'P1','P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9'))# to keep the line and bar legends separate:#  you can simply draw a legend on each one, since each#  respective Axes holds onto its own data/artistsax.legend(loc="upper left")twin_x.legend(loc="upper left", bbox_to_anchor=(0, .85)) # To create 1 all encompassing legend:#  you can use fig.legend with some tweaking#  fig.legend automatically gathers legend information from all Axes on the figure#  we'll need to give it a bounding box, as well as a new coordinate system so#  that it will appear inside of the bounds of the Axes (instead of the bounds of the figure)fig.legend(bbox_to_anchor=(.9, 1), bbox_transform=ax.transAxes)# Legends on the left are the legends we made with ax.legend(...) + twin_x.legend(...)# legend on the right is the all encompassing fig.legend(...)plt.show()无论代码行的顺序如何,该解决方案都将起作用,因为我们告诉 pandas 在特定轴上绘制,而不是让它选择在一组现有轴上绘制或创建一个新轴。编辑:手动指定 zorder 是控制元素绘制顺序的可靠方法。本质上,具有较高 zorder 的元素将位于具有较低 zorder 的元素之上。在本例中,我们的网格的 zorder 为 0,条形图和线条的 zorder 为 1 和 2,确保它们将放置在网格的顶部(因为它们的 zorder 高于 0)。编辑2(添加图例):左边的图例是我们用 ax.legend(...) + twin_x.legend(...) 创建的图例右侧的图例是无所不包的Fig.legend(...) 有关方法的描述,请参阅代码中的注释

忽然笑

以下两轴图方法很简单,因为它保留索引并包含图例。# This two line sequence has the problem# m1_t['A'].plot(kind='bar',colormap=cmap1)# m1_t[['B','C']].plot(kind='line',secondary_y=True,colormap=cmap2)ax = m1_t.plot(y='A', kind='bar',colormap=cmap1)ax1 = m1_t.plot(y=['B','C'], kind='line',secondary_y=True,colormap=cmap2, ax=ax)
随时随地看视频慕课网APP
我要回答