Bagaimana cara mengatur skala centang sebagai pangkat 2 di matplotlib? [duplikat]

Dec 16 2020

Saya ingin memplot sosok yang nilai xticknya tumbuh pada pangkat 2.

Sebagai contoh,

import pandas as pd
data = pd.DataFrame({
    'x': [2, 4, 8, 16, 32, 64],
    'y': [1, 2, 3, 4, 5, 6]
})

Yang saya harapkan adalah sosok seperti ini,

Untuk data yang rapi seperti contoh di atas, saya hanya dapat membuat kolom tambahan x21 ~ 6 di dataframe ini dan kemudian mengatur xticklabels dari gambar tersebut ke 2 ^ 1 ~ 2 ^ 6. Namun, solusi ini tidak berlaku untuk situasi dengan nilai lain seperti 3, 7, atau 30.

Sepertinya matplotlib hanya mendukung skala log. Bagaimana saya bisa mencapai centang dengan skala pangkat 2?

Jawaban

max Dec 16 2020 at 17:20

Ini adalah pertanyaan yang sangat jebakan (yang tidak saya duga ^^).

Oke, mari kita mulai dengan beberapa petunjuk untuk membaca: Anda ingin menyetel skala x / y: .matplotlib.axes.Axes.set_yscale () . Meskipun ada beberapa skala standar (standarnya jelas 'liner', seseorang dapat menyetel skala kustom. Berikut adalah beberapa contoh bagus.

Pada dasarnya, Anda mendefinisikan dua fungsi dengan transformasi maju dan dengan kebalikannya . Setelah itu Anda perlu mengatur tanda centang dengan benar (karena Anda menerapkan transformasi setelah memplot, tanda centang tetap sama (tetapi tidak pada posisi yang sama karena transformasi). Ada dua pilihan untuk ini:

  • mengatur tanda centang secara manual matplotlib.axes.Axes.set_xticks(), atau
  • dengan menetapkan locator sumbu: matplotlib.axes.Axes.xaxis.set_major_locator(). Ini disarankan jika Anda menggunakan kisi. Tetapi karena pengetahuan saya terbatas, saya menghargai penjelasan yang lebih detail (karena sekarang saya juga penasaran dengan fitur ini ^^)

Dan sekarang sampai pada bagian yang sulit: memformat label centang untuk mewakili a '2^x'. Saya tidak menemukan ide yang lebih baik daripada menetapkannya secara eksplisit sebagai string. Tampaknya seseorang dapat mengubah format umum hanya dalam batasan terbatas, lihat matplotlib.pyplot.ticklabel_format(), di mana seseorang dapat memilih jika dan kapan sebuah notasi ilmiah harus digunakan (yaitu menampilkan a '10^x'di kanan bawah). Beri tahu saya jika ada solusi yang lebih umum untuk ini.

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.ticker import FixedLocator

# create dummy data
df = pd.DataFrame({
    'x': [2**x for x in range(1,10)],
    'y': list(range(1,10))
})

def forward(x):
    return np.log2(x)


def inverse(x):
    return 2**x

# open figure
fig, ax = plt.subplots(2,2)
axs = ax.flatten()
for i in range(0,4):
    # plot data
    axs[i].plot(df['x'],df['y'])
    if i > 0:
        # set scale function
        axs[i].set_xscale('function', functions=(forward,inverse))
    if i > 1:
        # set ticks
        # - OPTION 1
        axs[i].set_xticks(df['x'])
        # - OPTION 2
      axs[i].xaxis.set_major_locator(FixedLocator(2**np.arange(1,10)))
    if i > 2:
        # est tick labels
        axs[i].set_xticklabels( [f"2^{j:.0f}" for j in np.log2(df['x'])] )

plt.show()