Python >> Python opplæring >  >> Python Tag >> Matplotlib

Hvordan justerer jeg rutenett for to y-akseskalaer ved å bruke Matplotlib?

Jeg er ikke sikker på om dette er den peneste måten å gjøre det på, men det fikser det med én linje:

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

np.random.seed(0)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')

# ADD THIS LINE
ax2.set_yticks(np.linspace(ax2.get_yticks()[0], ax2.get_yticks()[-1], len(ax1.get_yticks())))

plt.show()

Jeg kunne løse det ved å deaktivere ax.grid(None) i en av rutenettets akser:

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

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')
ax2.grid(None)

plt.show()


Jeg skrev denne funksjonen som tar Matplotlib-aksene objektene ax1, ax2 og flyter minresax1 minresax2:

def align_y_axis(ax1, ax2, minresax1, minresax2):
    """ Sets tick marks of twinx axes to line up with 7 total tick marks

    ax1 and ax2 are matplotlib axes
    Spacing between tick marks will be a factor of minresax1 and minresax2"""

    ax1ylims = ax1.get_ybound()
    ax2ylims = ax2.get_ybound()
    ax1factor = minresax1 * 6
    ax2factor = minresax2 * 6
    ax1.set_yticks(np.linspace(ax1ylims[0],
                               ax1ylims[1]+(ax1factor -
                               (ax1ylims[1]-ax1ylims[0]) % ax1factor) %
                               ax1factor,
                               7))
    ax2.set_yticks(np.linspace(ax2ylims[0],
                               ax2ylims[1]+(ax2factor -
                               (ax2ylims[1]-ax2ylims[0]) % ax2factor) %
                               ax2factor,
                               7))

Den beregner og setter avmerkingene slik at det er syv haker. Den laveste haken tilsvarer den gjeldende laveste haken og øker den høyeste haken slik at separasjonen mellom hver hake er heltallsmultipler av minrexax1 eller minrexax2.

For å gjøre det generelt, kan du angi det totale antallet haker du vil ha ved å endre 7. du ser til det totale antallet haker, og endrer 6 til totalt antall haker minus 1.

Jeg legger inn en pull-forespørsel for å inkludere noe av dette i matplotlib.ticker.LinearLocator:

https://github.com/matplotlib/matplotlib/issues/6142

I fremtiden (kanskje Matplotlib 2.0?), prøv:

import matplotlib.ticker
nticks = 11
ax1.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))
ax2.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))

Det burde bare fungere og velg praktiske haker for begge y-aksene.