почему на моей цветовой полосе есть линии?

Редактировать: поскольку это популярное сообщение, вот решение, которое, похоже, хорошо работает для меня. Спасибо @gazzar и @mfra.

cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")

Кто-нибудь знает, почему на моей цветовой полосе есть то, что кажется линиями? А точнее почему переход цвета не плавный? Очевидно, я использую базовую карту, но это не должно иметь значения, поскольку все вызовы matplotlib находятся под капотом AFAICT. Я создаю карту, делая что-то вроде

grays = plt.cm.get_cmap("Grays")
sc = mymap.scatter(xpoints, ypoints, s=sizes, c=color_values, cmap=grays, alpha=.75,
                   marker="o", zorder=10, vmin=0, vmax=1)
cbar = mymap.colorbar(sc, drawedges=True, location="bottom")

Пробовал и без альфы и без альфы и результат был тот же. Может быть, это потому, что мой массив color_values ​​недостаточно хорош? Могу ли я где-нибудь установить базовые значения, которые сопоставляются с цветовой полосой? Я не вижу, как, и я не вижу этой проблемы в другом месте. То есть я могу воспроизвести пример matplotlib show_colorbars без этой проблемы.

Пример неудачной цветной полосы


person jseabold    schedule 21.02.2013    source источник
comment
Вы пробовали сохранять фигуру в разных форматах? Если да, всегда ли у вас возникают эти проблемы?   -  person Francesco Montesano    schedule 21.02.2013
comment
Я видел это только в результате альфы, вы действительно уверены, что то же самое с альфой = 1.0?   -  person Rutger Kassies    schedule 21.02.2013
comment
Да, это происходит с png, но я не устранял эту проблему. Да, я видел это для alpha = 1.0 с SVG.   -  person jseabold    schedule 22.02.2013
comment
Хм... ни один из перечисленных ниже вариантов, похоже, не решает проблему для меня. На моей цветовой полосе все еще есть белые линии, когда я сохраняю рисунок в формате PDF.   -  person nukeguy    schedule 19.08.2015
comment
Две строки, данные в качестве решения в последнем редактировании, не должны использоваться вместе. Либо того, либо другого достаточно.   -  person divenex    schedule 05.10.2015
comment
Вот предлагаемый обходной путь с расчетными имитированными значениями альфа: stackoverflow.com/a/64201085/2084944   -  person Tik0    schedule 05.10.2020


Ответы (7)


Если вы создаете векторную графику, пробовали ли вы это (взято с http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar):

«Известно, что некоторые средства просмотра векторной графики (svg и pdf) отображают белые промежутки между сегментами цветовой полосы. Это связано с ошибками в средствах просмотра, а не в matplotlib. В качестве обходного пути цветовую полосу можно отображать с перекрывающимися сегментами:

cbar = colorbar()
cbar.solids.set_edgecolor("face")
draw()

Однако это имеет негативные последствия в других обстоятельствах. В частности, с полупрозрачными изображениями (альфа ‹ 1) и расширениями цветовых полос, которые не включены по умолчанию, см. (ошибка № 1188).

person mfra    schedule 22.02.2013
comment
Спасибо. Это действительно кажется проблемой при чтении # 1188 и прикрепленного (обратного) PR. Интересно также, что SVG по-разному отображаются в Firefox и Chrome, о чем я не подумал. - person jseabold; 22.02.2013
comment
Похоже, что наилучшие результаты для альфы ‹ 1 получаются при использовании drawedges=False и set_edgecolor(face). Теперь у меня есть черные линии, но они менее выражены и только в более темных тонах. - person jseabold; 22.02.2013
comment
Это действительно ошибка в средстве просмотра, но также верно и то, что для рендеринга цветовой полосы используется неоптимальный способ. Вся фигура должна быть нарисована как единое целое с использованием плавной заливки, а не 256 маленьких прямоугольников. Форматы PDF и SVG поддерживают линейное плавное затенение с произвольным количеством цветов. - person Mojca; 05.03.2014

Похоже, ваш график использует некоторые прозрачные (альфа) значения. У меня была такая же проблема (полупрозрачный график, но я хотел, чтобы цветная полоса была сплошной), и этот вопрос и ответ исправили это для меня! Для справки:

cbar.set_alpha(1)
cbar.draw_all()
person Wesley Baugh    schedule 26.03.2013
comment
Это изменило мою цветовую карту в цветовой панели! Почему?? Какого черта :D - person Rylan Schaeffer; 23.05.2020

Я попробовал обе настройки, указанные в других комментариях, а именно

cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")

и, к сожалению, ни один из них не работал для меня.

Поэтому я попробовал совершенно другой подход, который представляет собой огромный хак, но, по крайней мере, выполняет свою работу. Когда вы передаете alpha в imshow, он устанавливает альфа-значение, которое будет использоваться для смешивания с другими изображениями. Из-за более высокой мощности (как упоминал @mfra) это создает белые линии, которые мы так презираем. Ясно, что ключевым моментом является не передача альфа-значения в imshow. Однако нам все еще нужно как-то создать цветовую полосу.

Таким образом, в качестве обходного пути мы можем сделать альфа-смешивание самостоятельно, прежде чем давать цветовые карты для imshow. В качестве примера воспользуемся цветовой картой winter:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

xx, yy = np.meshgrid(np.linspace(-1, 1, 100), np.linspace(-1, 1, 100))
zz = xx**2 + yy**2

my_cmap_rgb = plt.get_cmap('winter')(np.arange(256))
alpha = 0.5

for i in range(3): # Do not include the last column!
    my_cmap_rgb[:,i] = (1 - alpha) + alpha*my_cmap_rgb[:,i]
my_cmap = mpl.colors.ListedColormap(my_cmap_rgb, name='my_cmap')

Здесь я создаю новую цветовую карту my_cmap_rgb на основе winter, а затем редактирую не-альфа-каналы (0, 1 и 2), чтобы самостоятельно выполнить альфа-смешивание. Затем я могу просто использовать эту новую карту цветов для построения своей фигуры.

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap=my_cmap)
cbar = plt.colorbar(cim)
ax.set_title("No lines and no transparency")

Нет линий и  нет прозрачности Теперь сравните его с изображением, которое вы бы получили без этого трюка:

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap='winter', alpha=0.5)
cbar = plt.colorbar(cim)
ax.set_title("Lines and transparency")

Линии и прозрачность

Ясно, что проблема решена, если вам не нужна прозрачность. С другой стороны, если вам нужна прозрачность, есть еще один обходной путь. Вы должны сначала построить изображение без прозрачности, чтобы получить цветовую полосу, а затем построить изображение с прозрачностью, но чья цветовая полоса не будет использоваться.

f, ax = plt.subplots()
cim = ax.imshow(zz, cmap=my_cmap)
cbar = plt.colorbar(cim)
plt.cla()  # Clears axis
ax.plot(50,50, 'ko')
ax.imshow(zz, cmap='winter', alpha=0.5)
ax.set_title("No lines and transparency")

Это приводит к изображению, цветовая полоса которого не имеет линий, но при этом сохраняет прозрачность. Хотя это остается массовым взломом, по крайней мере, нам больше не нужно мириться с этими строками!

Никаких линий и прозрачности

person cako    schedule 27.02.2016
comment
Я применил последний трюк (график без альфы, график с цветной полосой, график с альфой), так как мне приходилось запускать изображения через imshow, при этом второе прозрачно накладывалось на первое, а второе имело цветовую полосу. При этом натыкаемся на прозрачно-полосатую выдачу. - person ; 20.04.2016

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

cbar.solids.set_rasterized(True) 

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

person gazzar    schedule 15.08.2014
comment
Вернемся к этому два года спустя. Это действительно немного помогает. - person jseabold; 26.04.2015
comment
Превосходно. Выглядит лучше, а вывод SVG меньше! - person Bram; 24.12.2015

Пытаться:

cbar = mymap.colorbar(sc, drawedges=False, location="bottom")

Теперь это хорошо задокументировано в Интернете (что я мог найти), но

*drawedges*   [ False | True ] If true, draw lines at color
              boundaries.

(взято из matplotlib/lib/matplotlib/colorbar.py) Я думаю, что, установив drawedges в True, вы говорите ему рисовать эти линии.

person tacaswell    schedule 21.02.2013
comment
drawedges действительно рисует для меня края, но рисует их черным цветом! Не особенно полезно. Решение mfra у меня работает без задержек. (матплотлиб v1.3.1) - person travc; 24.10.2014

Поскольку ни одно из других предложений не сработало для меня, я удалил альфа-канал из экземпляра панели цветов:

from matplotlib.colors import to_rgb

lut = colorbar.solids.get_facecolor()
bg_color = to_rgb('white')
lut[:, :3] *= lut[:, 3:]
lut[:, :3] += (1 - lut[:, 3:]) * bg_color
lut[:, 3] = 1.
colorbar.solids.set_facecolor(lut)

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

person christianbrodbeck    schedule 29.01.2018

Следующее может быть другим решением, даже если оно не элегантно.

In [1]: children = cbar.ax.get_children()
In [2]: children
Out[2]:
[<matplotlib.collections.QuadMesh at 0x21783c41b70>,
 <matplotlib.collections.LineCollection at 0x21783bfdc18>,
 <matplotlib.patches.Polygon at 0x21783ba0588>,
 <matplotlib.patches.Polygon at 0x21783beef98>,
 <matplotlib.spines.Spine at 0x21783b77c88>,
 <matplotlib.spines.Spine at 0x21783b77470>,
 <matplotlib.spines.Spine at 0x21783b70c88>,
 <matplotlib.spines.Spine at 0x21783b70860>,
 <matplotlib.axis.XAxis at 0x21783b6ac50>,
 <matplotlib.axis.YAxis at 0x21783ba60f0>,
 <matplotlib.text.Text at 0x21783bc2198>,
 <matplotlib.text.Text at 0x21783bc2320>,
 <matplotlib.text.Text at 0x21783bc22b0>,
 <matplotlib.patches.Rectangle at 0x21783bc2358>]
In [3]: obj = children[1]  # Get the LineCollection object
In [4]: obj.set_linewidth(0)
person Daewon Lee    schedule 11.11.2017