Python - dual y axis chart, align zero

爷,独闯天下 提交于 2021-02-11 09:18:10

问题


I'm trying to create a horizontal bar chart, with dual x axes. The 2 axes are very different in scale, 1 set goes from something like -5 to 15 (positive and negative value), the other set is more like 100 to 500 (all positive values).

When I plot this, I'd like to align the 2 axes so zero shows at the same position, and only the negative values are to the left of this. Currently the set with all positive values starts at the far left, and the set with positive and negative starts in the middle of the overall plot.

I found the align_yaxis example, but I'm struggling to align the x axes. Matplotlib bar charts: Aligning two different y axes to zero

Here is an example of what I'm working on with simple test data. Any ideas/suggestions? thanks

import pandas as pd
import matplotlib.pyplot as plt

d = {'col1':['Test 1','Test 2','Test 3','Test 4'],'col 2':[1.4,-3,1.3,5],'Col3':[900,750,878,920]}
df = pd.DataFrame(data=d)

fig = plt.figure()  # Create matplotlib figure

ax = fig.add_subplot(111)  # Create matplotlib axes
ax2 = ax.twiny()  # Create another axes that shares the same y-axis as ax.

width = 0.4

df['col 2'].plot(kind='barh', color='darkblue', ax=ax, width=width, position=1,fontsize =4, figsize=(3.0, 5.0))
df['Col3'].plot(kind='barh', color='orange', ax=ax2, width=width, position=0, fontsize =4, figsize=(3.0, 5.0))

ax.set_yticklabels(df.col1)
ax.set_xlabel('Positive and Neg',color='darkblue')
ax2.set_xlabel('Positive Only',color='orange')

ax.invert_yaxis()
plt.show()

回答1:


I followed the link from a question and eventually ended up at this answer : https://stackoverflow.com/a/10482477/5907969

The answer has a function to align the y-axes and I have modified the same to align x-axes as follows:

def align_xaxis(ax1, v1, ax2, v2):
    """adjust ax2 xlimit so that v2 in ax2 is aligned to v1 in ax1"""
    x1, _ = ax1.transData.transform((v1, 0))
    x2, _ = ax2.transData.transform((v2, 0))
    inv = ax2.transData.inverted()
    dx, _ = inv.transform((0, 0)) - inv.transform((x1-x2, 0))
    minx, maxx = ax2.get_xlim()
    ax2.set_xlim(minx+dx, maxx+dx)

And then use it within the code as follows:

import pandas as pd
import matplotlib.pyplot as plt

d = {'col1':['Test 1','Test 2','Test 3','Test 4'],'col 2' [1.4,-3,1.3,5],'Col3':[900,750,878,920]}
df = pd.DataFrame(data=d)

fig = plt.figure()  # Create matplotlib figure

ax = fig.add_subplot(111)  # Create matplotlib axes
ax2 = ax.twiny()  # Create another axes that shares the same y-axis as ax.

width = 0.4

df['col 2'].plot(kind='barh', color='darkblue', ax=ax, width=width, position=1,fontsize =4, figsize=(3.0, 5.0))
df['Col3'].plot(kind='barh', color='orange', ax=ax2, width=width, position=0, fontsize =4, figsize=(3.0, 5.0))

ax.set_yticklabels(df.col1)
ax.set_xlabel('Positive and Neg',color='darkblue')
ax2.set_xlabel('Positive Only',color='orange')

align_xaxis(ax,0,ax2,0)
ax.invert_yaxis()
plt.show()

This will give you what you're looking for



来源:https://stackoverflow.com/questions/51034573/python-dual-y-axis-chart-align-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!