python 映射 盘_使用Python / Matplotlib基于色彩映射绘制(极性)色轮

I am trying to create a color wheel in Python, preferably using Matplotlib. The following works OK:

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([])

However, this attempt has two serious drawbacks.

First, when saving the resulting figure as a vector (figure_1.svg), the color wheel consists (as expected) of 621 different shapes, corresponding to the different (x,y) values being plotted. Although the result looks like a circle, it isn't really. I would greatly prefer to use an actual circle, defined by a few path points and Bezier curves between them, as in e.g. matplotlib.patches.Circle. This seems to me the 'proper' way of doing it, and the result would look nicer (no banding, better gradient, better anti-aliasing).

Second (relatedly), the final plotted markers (the last few before 2*pi) overlap the first few. It's very hard to see in the pixel rendering, but if you zoom in on the vector-based rendering you can clearly see the last disc overlap the first few.

I tried using different markers (. or |), but none of them go around the second issue.

Bottom line: can I draw a circle in Python/Matplotlib which is defined in the proper vector/Bezier curve way, and which has an edge color defined according to a colormap (or, failing that, an arbitrary color gradient)?

解决方案

One way I have found is to produce a colormap and then project it onto a polar axis. Here is a working example - it includes a nasty hack, though (clearly commented). I'm sure there's a way to either adjust limits or (harder) write your own Transform to get around it, but I haven't quite managed that yet. I thought the bounds on the call to Normalize would do that, but apparently not.

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

This produces

If you want a ring rather than a wheel, use this before plt.show() or plt.savefig

display_axes.set_rlim([-1,1])

This gives

As per @EelkeSpaak in comments - if you save the graphic as an SVG as per the OP, here is a tip for working with the resulting graphic: The little elements of the resulting SVG image are touching and non-overlapping. This leads to faint grey lines in some renderers (Inkscape, Adobe Reader, probably not in print). A simple solution to this is to apply a small (e.g. 120%) scaling to each of the individual gradient elements, using e.g. Inkscape or Illustrator. Note you'll have to apply the transform to each element separately (the mentioned software provides functionality to do this automatically), rather than to the whole drawing, otherwise it has no effect.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值