条形图(主要)和线形图(次要)可以正常工作,但如果我更改代码中的顺序,则无法正常工作

2024-10-04 03:23:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要将这两个图放在一起,但当我使用条形图(主要)和线形图(次要)时,效果很好。如果我改变代码行中与绘图相关的顺序,它将不起作用

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()

The below graph shows and I need to collide them without changing the sequce of the graph.


Tags: importtrueaspltaxcolorpdcolors
2条回答

绘制此图的更好方法是使用面向对象的matplotlib api。首先我们必须定义Figureaxes,然后为了正确地绘制第二个y,我们将创建一个伪轴对象,该对象链接回我们创建的原始轴。然后我们可以告诉熊猫直接在我们的坐标轴上绘图,以确保一切都在正确的位置

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
import pandas as pd
import seaborn as sns

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='white') # we don't want the grid coming from seaborn

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]
})

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=ax
m1_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 later
m1_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/artists
ax.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()

enter image description here

无论代码行的顺序如何,这个解决方案都会起作用,因为我们告诉熊猫在特定轴上绘图,而不是让它选择在一组现有轴上绘图或创建一个新轴


编辑:

手动指定zorder是控制元素绘制顺序的可靠方法。本质上,具有较高zorder的元素将位于具有较低zorder的元素之上。在本例中,网格的zorder为0,条形图和线条的zorder为1和2,确保它们位于网格顶部(因为它们的zorder高于0)


编辑2(添加图例):

  • 左边的图例是我们用ax.legend(…)+twin_x.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)

enter image description here

相关问题 更多 >