使用Python/Matplotlib基于彩色地图绘制(极轴)色轮

2024-09-28 01:27:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在Python中创建一个色轮,最好使用Matplotlib。以下操作正常:

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

xval = np.arange(0, 2*pi, 0.01)
yval = np.ones_like(xval)

colormap = plt.get_cmap('hsv')
norm = mpl.colors.Normalize(0.0, 2*np.pi)

ax = plt.subplot(1, 1, 1, polar=True)
ax.scatter(xval, yval, c=xval, s=300, cmap=colormap, norm=norm, linewidths=0)
ax.set_yticks([])

Own attempt at creating a color wheel

然而,这种尝试有两个严重的缺点。

首先,当将生成的图形保存为矢量(figure_1.svg)时,色轮由621个不同形状组成(如预期),对应于正在绘制的不同(x,y)值。虽然结果看起来像一个圆圈,但实际上不是。我更喜欢使用一个实际的圆,由几个路径点和它们之间的Bezier曲线定义,例如^{}。在我看来,这是一种“正确”的方法,而且效果会更好(没有条带,更好的渐变,更好的抗锯齿)。

其次(相关地),最后绘制的标记(在2*pi之前的最后几个)与前几个重叠。在像素渲染中很难看到,但是如果放大基于矢量的渲染,可以清楚地看到最后一张光盘与前几张光盘重叠。

我试着使用不同的标记(.|),但没有一个是围绕第二个问题。

底线:我能用Python/Matplotlib画一个圆吗?这个圆是用合适的向量/Bezier曲线定义的,它的边颜色是根据一个颜色映射(或者,如果不能,任意的颜色梯度)定义的?


Tags: importnorm定义matplotlib颜色asnppi
2条回答

我只需要做一个色轮,决定更新rsnape的解决方案,使之与matplotlib 2.1兼容。您可以在极坐标图上绘制极坐标彩色网格,而不是将colorbar对象放置在轴上。

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

# If displaying in a Jupyter notebook:
# %matplotlib inline 

# Generate a figure with a polar projection
fg = plt.figure(figsize=(8,8))
ax = fg.add_axes([0.1,0.1,0.8,0.8], projection='polar')

# Define colormap normalization for 0 to 2*pi
norm = mpl.colors.Normalize(0, 2*np.pi) 

# Plot a color mesh on the polar plot
# with the color set by the angle

n = 200  #the number of secants for the mesh
t = np.linspace(0,2*np.pi,n)   #theta values
r = np.linspace(.6,1,2)        #radius values change 0.6 to 0 for full circle
rg, tg = np.meshgrid(r,t)      #create a r,theta meshgrid
c = tg                         #define color values as theta value
im = ax.pcolormesh(t, r, c.T,norm=norm)  #plot the colormesh on axis with colormap
ax.set_yticklabels([])                   #turn of radial tick labels (yticks)
ax.tick_params(pad=15,labelsize=24)      #cosmetic changes to tick labels
ax.spines['polar'].set_visible(False)    #turn off the axis spine.

它给出了:

A color wheel for the viridis colormap. Made with matplotlib 2.1.

我发现的一种方法是生成一个彩色地图,然后将其投影到极轴上。这是一个有效的例子-它包括一个讨厌的黑客,虽然(明确评论)。我确信有一种方法可以调整限制或者(更难)编写自己的Transform来绕过它,但我还没有完全做到这一点。我以为对Normalize的调用的界限可以做到这一点,但显然不行。

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

fig = plt.figure()

display_axes = fig.add_axes([0.1,0.1,0.8,0.8], projection='polar')
display_axes._direction = 2*np.pi ## This is a nasty hack - using the hidden field to 
                                  ## multiply the values such that 1 become 2*pi
                                  ## this field is supposed to take values 1 or -1 only!!

norm = mpl.colors.Normalize(0.0, 2*np.pi)

# Plot the colorbar onto the polar axis
# note - use orientation horizontal so that the gradient goes around
# the wheel rather than centre out
quant_steps = 2056
cb = mpl.colorbar.ColorbarBase(display_axes, cmap=cm.get_cmap('hsv',quant_steps),
                                   norm=norm,
                                   orientation='horizontal')

# aesthetics - get rid of border and axis labels                                   
cb.outline.set_visible(False)                                 
display_axes.set_axis_off()
plt.show() # Replace with plt.savefig if you want to save a file

这就产生了

colorwheel direct from matplotlib

如果你想要戒指而不是轮子,在plt.show()plt.savefig之前使用它

display_axes.set_rlim([-1,1])

这给了

color ring


根据注释中的@EelkeSpaak-如果您按照OP将图形保存为SVG,这里有一个处理结果图形的提示:结果SVG图像的小元素是接触的和不重叠的。这会导致某些渲染器(Inkscape、Adobe Reader,可能不是打印的)出现模糊的灰色线条。解决这个问题的一个简单方法是使用Inkscape或Illustrator对每个单独的渐变元素应用一个小的缩放比例(例如120%)。注意,您必须将转换分别应用于每个元素(所提到的软件提供了自动执行此操作的功能),而不是应用于整个图形,否则它不会产生任何效果。

相关问题 更多 >

    热门问题