Маркеры точек - графика - уродливые точки в сетиx [дубликат]

Если вы действительно хотите избавиться от предупреждений, одна вещь, которую вы можете сделать, это создать класс, который простирается от общего класса.

Например, если вы пытаетесь использовать

  private Map & lt; String, String & gt;  someMap = new HashMap & lt; String, String & gt; ();   

Вы можете создать новый класс, такой как

  public class StringMap extends HashMap & lt; String, String & gt; () {// Переписывать конструкторы}  

Тогда, когда вы используете

  someMap = (StringMap) getApplicationContext (). getBean ("someMap");   

Компилятор знает, что такое (более не общие) типы, и не будет никаких предупреждений. Это не всегда может быть идеальным решением, некоторые могут утверждать, что этот вид поражений предназначен для универсальных классов, но вы все еще повторно используете все одинаковые коды из общего класса, вы просто объявляете во время компиляции, какой тип вы хотите использовать.

20
задан Gabriel 11 July 2014 в 21:35
поделиться

5 ответов

Я просмотрел исходный код matplotlib. Плохая новость заключается в том, что не существует простого способа установить равные размеры точек в легенде. Это особенно сложно с диаграммами рассеяния (неправильно: см. Обновление ниже). Существуют две альтернативы:

  1. Измените код maplotlib
  2. Добавьте преобразование в объекты PathCollection, представляющие точки на изображении. Трансформация (масштабирование) должна учитывать исходный размер.

Ни одно из них не очень весело, хотя # 1 кажется более простым. scatter

import matplotlib.pyplot as plt
import numpy as np

def rand_data():
    return np.random.uniform(low=0., high=1., size=(100,))

# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]

plt.figure()
plt.plot(x1, y1, 'o', label='first', markersize=np.sqrt(20.), c='b')
plt.plot(x2, y2, 'o', label='second', markersize=np.sqrt(35.), c='r')
# Plot legend.
lgnd = plt.legend(loc="lower left", numpoints=1, fontsize=10)

#change the marker size manually for both lines
lgnd.legendHandles[0]._legmarker.set_markersize(6)
lgnd.legendHandles[1]._legmarker.set_markersize(6)
plt.show()

Это дает:

[/ g] g11] enter image description here [/g0]

Кажется, что вы хотели.

Изменения:

  • scatter изменены на plot, который изменяет масштаб маркера (следовательно, sqrt) и делает невозможным использование изменяемого размера маркера (если это было предназначено)
  • размер маркера изменен вручную, чтобы быть 6 точками для обоих маркеров в легенде

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

Обновить

Хаа, я нашел его. Лучше взломать:

import matplotlib.pyplot as plt
import numpy as np

def rand_data():
    return np.random.uniform(low=0., high=1., size=(100,))

# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]

plt.figure()
plt.scatter(x1, y1, marker='o', label='first', s=20., c='b')
plt.scatter(x2, y2, marker='o', label='second', s=35., c='r')
# Plot legend.
lgnd = plt.legend(loc="lower left", scatterpoints=1, fontsize=10)
lgnd.legendHandles[0]._sizes = [30]
lgnd.legendHandles[1]._sizes = [30]
plt.show()

Теперь _sizes (другое свойство подчеркивания) делает трюк. Не нужно прикасаться к источнику, хотя это довольно хак. Но теперь вы можете использовать все scatter.

enter image description here [/g1]

30
ответ дан DrV 17 August 2018 в 08:50
поделиться
  • 1
    синий должен быть меньше, но он должен быть прямо исправлен, +1 – Aprillion 11 July 2014 в 23:33
  • 2
    Удивительный ответ DrV! Извините, я не комментировал раньше, я думал, что у меня есть, но, видимо, я никогда не отправлял cmmt. – Gabriel 14 July 2014 в 16:34
  • 3
    Я просто хотел указать, что второй взлом больше не работает, по крайней мере для меня (python 3.5, matplotlib 1.5.1). Возможно, они что-то изменили в коде matplotlib. Первый работает, хотя, спасибо за это. – Sergey Antopolskiy 29 January 2017 в 20:25
  • 4
    Благодарю. Мне также нужно было переместить маркер, потому что он выглядел в странном месте после его изменения: lgnd.legendHandles[0]._offsets += np.array([[5,0]]) – Ian Hincks 30 August 2017 в 21:34

Аналогично ответу, если вы хотите, чтобы все маркеры имели одинаковый размер:

lgnd = plt.legend(loc="lower left", scatterpoints=1, fontsize=10)
for handle in lgnd.legendHandles:
    handle.set_sizes([6.0])

С MatPlotlib 2.0.0

6
ответ дан Bruno Morais 17 August 2018 в 08:50
поделиться

Вы можете создать объект Line2D, похожий на выбранные вами маркеры, за исключением другого размера маркера по вашему выбору и использовать его для построения легенды. Это приятно, потому что не требует размещения объекта в ваших осях (возможно, запускает событие изменения размера), и не требует использования каких-либо скрытых атрибутов. Единственный реальный недостаток заключается в том, что вы должны конструировать легенду явно из списков объектов и меток, но это хорошо документированная функция matplotlib, поэтому она очень удобна в использовании.

from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import numpy as np

def rand_data():
    return np.random.uniform(low=0., high=1., size=(100,))

# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]

plt.figure()
plt.scatter(x1, y1, marker='o', label='first', s=20., c='b')
plt.scatter(x2, y2, marker='o', label='second', s=35., c='r')

# Create dummy Line2D objects for legend
h1 = Line2D([0], [0], marker='o', markersize=np.sqrt(20), color='b', linestyle='None')
h2 = Line2D([0], [0], marker='o', markersize=np.sqrt(20), color='r', linestyle='None')

# Set axes limits
plt.gca().set_xlim(-0.2, 1.2)
plt.gca().set_ylim(-0.2, 1.2)

# Plot legend.
plt.legend([h1, h2], ['first', 'second'], loc="lower left", markerscale=2,
           scatterpoints=1, fontsize=10)
plt.show()

Ссылка на итоговую цифру

0
ответ дан Jeremy Bancroft Brown 17 August 2018 в 08:50
поделиться

У меня не было большого успеха, используя решение @ DrV, хотя, возможно, мой вариант использования уникален. Из-за плотности точек я использую наименьший размер маркера, т. Е. plt.plot(x, y, '.', ms=1, ...), и хочу, чтобы символы легенды были больше.

Я следил за рекомендацией, которую я нашел на форумах matplotlib :

  1. отображает данные (без меток)
  2. предел осей записи (xlimits = plt.xlim())
  3. отображает поддельные данные вдали от реальных данных с помощью
  4. Создать легенду

Вот как это получилось (для это точки на самом деле менее важны, чем линии):

Надеюсь, это поможет кому-то еще.

5
ответ дан Steven C. Howell 17 August 2018 в 08:50
поделиться
1
ответ дан ImportanceOfBeingErnest 29 October 2018 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: