Настройка меток x и y на диаграмме рассеяния matplotlib - PullRequest
1 голос
/ 21 марта 2020

У меня есть два списка xs и ys равной длины, которые я использую для рисования точечного графика:

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)

Однако я не хочу, чтобы стандартные метки оси, а скорее метки выводились Например, из следующих словарей:

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

Итак, я пытаюсь создать диаграмму рассеяния с меткой «Первый» в точке х = 40, «Второй» в точке х = 73 и т. д. on, а также «FIRST» при y = 10 и «SECOND» при y = 80. К сожалению, я не нашел способа достичь этого.

Большое спасибо!

1 Ответ

1 голос
/ 22 марта 2020

Чтобы отобразить метки в нужном месте, вы можете использовать:

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

Как вы заметили, это приводит к тому, что координаты больше не отображаются в строке состояния.

Обходной путь для отображения отображаемых координат, а также пользовательских тиков, использует custom tick formattter . Такой форматер получает два аргумента: значение x и значение pos. pos Нет при отображении координат в строке состояния, но установлено для меток тиков. Таким образом, отметив pos, а не None, форматировщик может вернуть нужную метку, в противном случае может быть возвращено число, отформатированное как строка. Позиции тиков по-прежнему необходимо устанавливать с помощью plt.xticks(), но не с помощью меток.

Вот пример:

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

...