Làm thế nào để đặt thang đánh dấu là lũy thừa của 2 trong matplotlib? [bản sao]

Dec 16 2020

Tôi muốn vẽ một hình có giá trị xtick tăng theo lũy thừa của 2.

Ví dụ,

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

Những gì tôi mong đợi là một con số như thế này,

Đối với dữ liệu gọn gàng như mẫu ở trên, tôi chỉ có thể tạo một cột phụ x2từ 1 ~ 6 trong khung dữ liệu này và sau đó đặt các nhãn xtick của hình thành 2 ^ 1 ~ 2 ^ 6. Tuy nhiên, cách giải quyết này không áp dụng cho các trường hợp có các giá trị khác như 3, 7 hoặc 30.

Có vẻ như matplotlib chỉ hỗ trợ thang đo nhật ký. Làm thế nào tôi có thể đạt được một đánh dấu với thang đo sức mạnh là 2?

Trả lời

max Dec 16 2020 at 17:20

Đây là một câu hỏi đặc biệt khó (mà tôi không mong đợi được ^^).

OK, hãy bắt đầu với một vài gợi ý để đọc: Bạn muốn đặt tỷ lệ x / y: .matplotlib.axes.Axes.set_yscale () . Mặc dù có một số thang đo tiêu chuẩn (hiển nhiên là mặc định 'liner', người ta có thể đặt thang đo tùy chỉnh. Dưới đây là một số ví dụ hay.

Về cơ bản, bạn xác định hai chức năng với mong chuyển đổi và với nghịch đảo của nó. Sau đó, bạn cần đặt các dấu kiểm một cách chính xác (vì bạn áp dụng phép biến đổi sau khi vẽ, các dấu tích vẫn giữ nguyên (nhưng không ở cùng một vị trí do phép biến đổi). Một người có hai tùy chọn cho việc này:

  • cài đặt tick theo cách thủ công matplotlib.axes.Axes.set_xticks(), hoặc
  • bằng cách thiết lập định vị của trục: matplotlib.axes.Axes.xaxis.set_major_locator(). Điều này được khuyến khích nếu bạn sử dụng lưới. Nhưng vì kiến ​​thức của tôi có hạn, tôi đánh giá cao một lời giải thích chi tiết hơn (vì bây giờ tôi cũng đang tò mò về tính năng này ^^)

Và bây giờ đến phần phức tạp: định dạng các nhãn đánh dấu để đại diện cho a '2^x'. Tôi đã không nghĩ ra một ý tưởng hay hơn là đặt chúng một cách rõ ràng dưới dạng chuỗi. Có vẻ như người ta chỉ có thể thay đổi định dạng chung trong các giới hạn hạn chế, hãy xem matplotlib.pyplot.ticklabel_format(), nơi người ta có thể chọn nếu và khi nào một ký hiệu khoa học nên được sử dụng (tức là hiển thị '10^x'ở dưới cùng bên phải). Hãy cho tôi biết nếu có một giải pháp chung hơn cho việc này.

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