matplotlib 极坐标图周围的曲线文本

xoefb8l8  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(103)

我正在尝试在matplotlib中的极坐标图上弯曲文本。
以下是我的案例:

import matplotlib.pyplot as plt
import numpy as np
   
text = ["Electoral Process", "Political Pluralism", "Rule of Law",
            "Freedom of expression", "Freedom of believe"]

no_labels =len(text)
angle_size = int(360/no_labels)
#define the number of angles in degrees and convert it to radians 
theta = [i/180*np.pi for i in range(0, 360,angle_size) ]
#where to put the labels on the radial axis
radius = [1]*no_labels
#Find the mid point of each angle
mid_point =[i/180*np.pi for i in range(int(angle_size/2), 360, angle_size)]

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'},figsize=(10, 6), facecolor="white")

ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_xticklabels([]) #remove the original xlabels
ax.set_yticklabels([])  #remove the original ylabels

# Arrange the grid into number of sales equal parts in degrees
lines = plt.thetagrids(range(0, 360, int(360/len(text))))

#Place the text in the midle of each pie
for m, r, t in zip(mid_point,radius, text):
    ax.annotate(t, xy=[m, r], fontsize=12,  ha="center", va="center",  )

这会生成以下内容:

我已经找到了其他这样做的帖子,但我不理解代码,所以我试图从头开始构建它。这是我到目前为止得到的:

import numpy as np 
import matplotlib as mpl 

text = ["Electoral Process", "Political Pluralism", "Rule of Law",
            "Freedom of expression", "Freedom of believe"]

no_labels =len(text)
angle_size = int(360/no_labels)
#define the number of angles in degrees and convert it to radians 
theta = [i/180*np.pi for i in range(0, 360,angle_size) ]
#where to put the labels on the radial axis
radius = [1]*no_labels
#Find the mid point of each angle
mid_point =[i/180*np.pi for i in range(int(angle_size/2), 360, angle_size)]

fig,ax=plt.subplots(subplot_kw={'projection': 'polar'},figsize=(10,6), dpi=100)

# Arrange the grid into number of sales equal parts in degrees
lines = plt.thetagrids(range(0, 360, int(360/len(text))))

ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_xticklabels([]) #remove the original xlabels
ax.set_yticklabels([])  #remove the original ylabels

#start with one label

start_text = theta[0]
text2=["ELECTORAL PROCESS"]
spacing=len(text[0])+4
end_text = theta[1]

x= np.linspace(start_text, end_text, spacing)
y= [1, 0.5]

for txt in text2:
    print(txt)
    for a,tx in zip(x,txt):
        ax.text(a, 1.05 ,tx,rotation=-28, fontsize= 8, ha="center", va= "center"),
print(a,tx)

生成如下结果:

现在,我必须为每个标签添加它,旋转每个字母以遵循曲线(目前使用硬编码的Angular ),并根据代码的位置向上或向下书写,看起来我可能会使事情变得复杂。
有人用“简单的代码”做过这件事吗?或者可以解释下面的代码是如何工作的?
Similar problem but dont understand the code

093gszye

093gszye1#

这是一个非常困难的问题,这是我经过2个小时的编码后得到的(我不能做得更好)。

# Import modules
import numpy as np 
import matplotlib.pyplot as plt 
# ------------------------------------ # 
  
# Define the figure
fig = plt.figure(figsize=(16,16))
# Setting the axes projection as polar 
ax = fig.add_subplot(111, projection='polar')

# List that stores 
# - the text to be displayed 
# - the distance, r, from the center
# - the angle at which to display the text
# 
# data = [["text", r, theta in deg], [...], ...]
#  The r and theta have to be hardcoded
#
data = [["Electoral Process",  1.02, 65.0], ["Political Pluralism", 1.04,  -5.0], ["Rule of Law", 1.06, -95.0],
        ["Freedom of expression", 1.06, 215.0], ["Freedom of believe", 1.06, 137.0]]

# Arrange the grid into number of sales equal parts in degrees
lines = plt.thetagrids(range(0, 360, int(360/len(data))))

# Iterate through each text
for text, r, theta in data:

     # Convert to radians
     theta = np.deg2rad(theta)

     # Iterate through each letter
     for i in range(len(text)):
          
          # Display the letter
          #
          # The angle of rotation is -(90 deg - theta). 
          # This makes a right angle triangle. We must rotate the text towards Center. 
          # Please draw it on paper, with the angle, theta, to get why the equation is correct.
          # 
          #                      text[i]
          #                        |
          #                        |
          # Center ----------------|
          # 
          plt.text(theta, r, text[i], rotation=-(90-np.rad2deg(theta)), fontsize=16)

          # Decrement theta for the next letter
          theta -= 0.06  # Arbirary value

# Remove tick labels
ax.set_xticklabels([])
ax.set_yticklabels([])

# Display the plot
plt.show()

结果如下:

我希望这对你有帮助。

v09wglhw

v09wglhw2#

感谢@aradhna,我设法修复了代码。(万分感谢)在这里!

import numpy as np 
import matplotlib.pyplot as plt

text = ["Electoral Process", "Political Pluralism", "Rule of Law",
            "Freedom of expression", "Freedom of believe"]

no_labels =len(text)
angle_size = int(360/no_labels)
#define the number of angles in degrees and convert it to radians 
theta = [i/180*np.pi for i in range(0, 360,angle_size) ]
#Find the mid point of each angle
mid_point =[i/180*np.pi for i in range(int(angle_size/2), 360, angle_size)]

fig,ax=plt.subplots(subplot_kw={'projection': 'polar'},figsize=(10,6), dpi=100)

# Arrange the grid into number of text
lines = plt.thetagrids(range(0, 360, int(360/len(text))))

ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_xticklabels([]) #remove the original xlabels
ax.set_yticklabels([])  #remove the original ylabels

for txt,  midpoint in zip(text, mid_point):
    #count nr letters divide by 2 convert to radians and substract from midpoiint
    center_pos = midpoint-np.deg2rad(len(txt)/2+4)
    #print(midpoint, text, a)
    for i in range(len(txt)):     
        #print(txt[i], midpoint, a)      
        ax.text(center_pos, 1.04 ,txt[i].capitalize(),rotation=-np.rad2deg(center_pos), fontsize= 8, ha="center", va= "center")
        center_pos += 0.032 #adds radians to the next275 letter

结果如下:

相关问题