Mam dwie listy xs i ys równej długości, której używam, aby narysować wykres rozproszony:

import random
import matplotlib.pyplot as plt

xs = [random.randrange(0,100) for i in range(50)]
ys = [random.randrange(0,100) for i in range(50)]

plt.scatter(xs,ys)

Nie chcę jednak standardowych etykiet osi, ale raczej etykiety wywnioskowane, np. Następujące słowniki:

x_labels = { 40 : "First", 52 : "Second", 73: "Third" , 99: "Forth" }
y_labels = { 10 : "FIRST", 80 : "SECOND" }

Więc co próbuję zrobić, to mieć wykres rozproszony z etykietą "pierwszą" w X = 40, "Drugi" w X = 73 i tak dalej, a także "pierwszy" w Y = 10 i "Drugi" w y = 80. Niestety, nie znalazłem sposobu, jak to osiągnąć.

Wielkie dzięki!

1
Alex W. 21 marzec 2020, 18:32

1 odpowiedź

Najlepsza odpowiedź

Aby wyświetlić etykiety kleszcza w żądanej pozycji, możesz użyć:

plt.xticks(list(x_labels.keys()), x_labels.values())
plt.yticks(list(y_labels.keys()), y_labels.values())

Jak zauważyłeś, ma to w konsekwencji, że współrzędne nie są wyświetlane w pasku stanu.

Obejście, aby uzyskać wyświetlane współrzędne, jak również zwyczajowe kleszcze, używa Niestandardowy kleszczy format. Taki format ma dwa argumenty: wartość x i pos. pos nie jest żadnym, wyświetlając współrzędne na pasku stanu, ale jest ustawiony dla etykiet kleszczy. Tak więc sprawdzanie pos nie, formated może zwrócić żądaną etykietę, a w przeciwnym razie liczba sformatowana jako ciąg może zostać zwrócona. Pozycje kleszczowe nadal muszą być ustawione przez plt.xticks(), ale nie etykiety.

Oto przykład:

import random
import matplotlib.pyplot as plt
from matplotlib import ticker

@ticker.FuncFormatter
def major_x_formatter(x, pos):
    if pos is not None:
        return f"{x_labels_list[pos]}"
    x_r = int(round(x))
    if x_r in x_labels:
        return f"{x:.0f}:{x_labels[x_r]}"
    else:
        return f"{x:.2f}"

@ticker.FuncFormatter
def major_y_formatter(y, pos):
    if pos is not None:
        return f"{y_labels_list[pos]}"
    y_r = int(round(y))
    if y_r in y_labels:
        return f"{y:.0f}:{y_labels[y_r]}"
    else:
        return f"{y:.2f}"

xs = [random.randrange(0,100) for i in range(50)]
ys = [random.randrange(0,100) for i in range(50)]

plt.scatter(xs,ys)

x_labels = { 40 : "First", 52 : "Second", 73: "Third" , 99: "Forth" }
x_labels_list = list(x_labels.values())
y_labels = { 10 : "FIRST", 80 : "SECOND" }
y_labels_list = list(y_labels.values())
plt.xticks(list(x_labels.keys()))
plt.yticks(list(y_labels.keys()))
plt.gca().xaxis.set_major_formatter(major_x_formatter)
plt.gca().yaxis.set_major_formatter(major_y_formatter)

plt.show()

resulting plot

1
JohanC 22 marzec 2020, 13:53