繁体   English   中英

我有一个数据框 df,我想绘制一个径向条形图/柱形图,其中的值映射到城市

[英]I have a dataframe df and I want to draw a radial bar/column chart with the values mapped against the cities

我有一个数据框 df,我想绘制一个径向条形图/柱形图,其中的值映射到城市。

数据框看起来像:

城市 计数
利兹 5个
利物浦 7
伯明翰 8个
诺丁汉 14

我能够得到水平条形图但不能得到径向条形图

colors = ["red","green","blue","yellow","magenta","cyan"]
plt.barh("state", "counts", data = m, color = colors)
plt.xlabel("Number of Firearm Incidents per head")
plt.ylabel("LSOA Region")
plt.title("Firearm Incidents vs LSOA per head")
plt.show()

我想要像这两个这样的东西1 2

这是一种可能的方法:

# import pandas for data wrangling
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Build a dataset
df = pd.DataFrame({'City': ['Leeds', 'Liverpool', 'Birmingham', 'Nottingham'],
                   'Counts': [5, 7, 8, 14]})

# Reorder the dataframe
df = df.sort_values(by=['Counts'])

# initialize the figure
plt.figure(figsize=(20,10))
ax = plt.subplot(111, polar=True)
plt.axis('off')

# Constants = parameters controling the plot layout:
upperLimit = 100
lowerLimit = 30
labelPadding = 4

# Compute max and min in the dataset
max = df['Counts'].max()

# Let's compute heights: they are a conversion of each item value in those new coordinates
# In our example, 0 in the dataset will be converted to the lowerLimit (10)
# The maximum will be converted to the upperLimit (100)
slope = (max - lowerLimit) / max
heights = slope * df.Counts + lowerLimit

# Compute the width of each bar. In total we have 2*Pi = 360°
width = 2*np.pi / len(df.index)

# Compute the angle each bar is centered on:
indexes = list(range(1, len(df.index)+1))
angles = [element * width for element in indexes]
angles

# Draw bars
bars = ax.bar(
    x=angles, 
    height=heights, 
    width=width, 
    bottom=lowerLimit,
    linewidth=2, 
    edgecolor="white",
    color="#61a4b2",
)

# Add labels
for bar, angle, height, label in zip(bars,angles, heights, df["City"]):

    # Labels are rotated. Rotation must be specified in degrees :(
    rotation = np.rad2deg(angle)

    # Flip some labels upside down
    alignment = ""
    if angle >= np.pi/2 and angle < 3*np.pi/2:
        alignment = "right"
        rotation = rotation + 180
    else: 
        alignment = "left"

    # Finally add the labels
    ax.text(
        x=angle, 
        y=lowerLimit + bar.get_height() + labelPadding, 
        s=label, 
        ha=alignment, 
        va='center', 
        rotation=rotation, 
        rotation_mode="anchor") 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM