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

Eel*_*aak 17 python plot colors matplotlib scipy

我试图用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([])
Run Code Online (Sandbox Code Playgroud)

自己尝试创建色轮

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

首先,当将结果图形保存为矢量(figure_1.svg)时,色轮包含(如预期)621种不同的形状,对应于绘制的不同(x,y)值.虽然结果看起来像一个圆圈,但事实并非如此.我更倾向于使用一个实际的圆,由几个路径点和它们之间的贝塞尔曲线定义,如例如matplotlib.patches.Circle.这在我看来是"正确"的方式,结果看起来更好(没有条带,更好的渐变,更好的抗锯齿).

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

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

底线:我可以在Python/Matplotlib中绘制一个圆圈,它以适当的矢量/贝塞尔曲线方式定义,并且具有根据色彩图定义的边缘颜色(或者,失败,任意颜色渐变)?

J R*_*ape 15

我找到的一种方法是生成一个色图,然后将其投影到极轴上.这是一个工作的例子 - 它包括一个令人讨厌的黑客,但(明确评论).我确信有一种方法可以调整限制或者(更难)编写自己的方法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
Run Code Online (Sandbox Code Playgroud)

这产生了

colorwheel直接来自matplotlib

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

display_axes.set_rlim([-1,1])
Run Code Online (Sandbox Code Playgroud)

这给了

色环


根据评论中的@EelkeSpaak - 如果按照OP将图形保存为SVG,这里有一个处理结果图形的提示:生成的SVG图像的小元素是触摸和非重叠的.这会导致某些渲染器出现微弱的灰色线条(Inkscape,Adobe Reader,可能没有打印).对此的简单解决方案是使用例如Inkscape或Illustrator对每个单独的梯度元素应用小的(例如120%)缩放.请注意,您必须单独将变换应用于每个元素(所提到的软件提供自动执行此操作的功能),而不是整个绘图,否则它不起作用.


小智 7

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

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.
Run Code Online (Sandbox Code Playgroud)

它给出了:

绿配色图的色轮。 用matplotlib 2.1制作。