简体   繁体   中英

In python, how can I fill up each bar in a bar chart with its constituent data?

This picture is an example of what I have up until this point. I have values stored in some lists that represent the composition of each bar. And, I want to show that composition with different patterns or colors in the same chart. Can someone help me with this or give me any link that can help? Thank you!

import matplotlib.pyplot as plt

def plotFigure(challenged_list, noeffect_list, reinforced_list,challenged_extra_list,challenged_agree_list,
           challenged_cons_list,challenged_neuro_list,challenged_open_list):
labels = ['Topic 1', 'Topic 2', 'Topic 3', 'Topic 4', 'Topic 5', 'Topic 6', 'Topic 7', 'Topic 8', 'Topic 9',
          'Topic 10', 'Topic 11', 'Topic 12', 'Topic 13',
          'Topic 14', 'Topic 15', 'Topic 16', 'Topic 17', 'Topic 18', 'Topic 19', 'Topic 20', 'Topic 21',
          'Topic 22', 'Topic 23', 'Topic 24', 'Topic 25', 'Topic 26',
          'Topic 27']
x = np.arange(len(labels))
width = 0.30

fig, ax = plt.subplots()

bar1 = ax.bar(x - width / 2, challenged_list, width, label='Challenged')
bar2 = ax.bar(x + width / 2, noeffect_list, width, label='No Effect')
bar3 = ax.bar(x + 3 * width / 2, reinforced_list, width, label='Reinforced')


ax.set_ylabel('Personality Traits Count')
ax.set_title('All In One')
ax.set_xticks(x)
ax.tick_params(axis='both', which='major', pad=15)
plt.xticks(rotation=60)
ax.set_xticklabels(labels)
ax.legend()
plt.show()

I'm not exactly sure what you are asking, but I think you are asking about putting patterns in the bar chart for different datasets? If so, then I have done something like this before using a cycler . With cyclers, you can compose different properties together (color, line thickness, opacity, hatch (pattern), etc.) when looping through lots of datasets. Below is a quick example... it's a bit cluttered, but I used 5 datasets to illustrate how the patterning works.

Edit: version 2 now has an option to stack the bars

#@ title Version 2
import matplotlib.pyplot as plt
import numpy as np
from cycler import cycler
from matplotlib.patches import Patch
import random


def patterned_bars_v2(N, num_sets=3, stacked=True, **prop_kwargs):

  make_data = lambda n: [random.randint(1, 10) for _ in range(n)]
  data = [make_data(N) for _ in range(num_sets)]

  colors = ['red', 'green', 'blue', 'orange']

  # These patterns can be made more coarse or fine. For more fine, just increase 
  # the number of identifiers. E.g. '/' -> coarse, '///' -> fine
  patterns = ['//', '++', '**', 'xx']


  color_cycler = cycler(color=colors)
  # Patterns are specified using the "hatch" property
  pattern_cycler = cycler(hatch=patterns)

  # 'Multiplication' of cyclers results in the 'outer product' of the two
  prop_cycler = pattern_cycler * color_cycler

  fig, ax = plt.subplots(figsize=(20, 10))

  width = 0.5
  xmax = (width * num_sets * N)* 1.1
  legend_handles = []

  bottom = np.zeros(N)

  for i, (data, props) in enumerate(zip(data, prop_cycler)):
    # Add passed in kwargs to props
    props.update(prop_kwargs)

    if stacked:
      xvals = np.arange(N)
      ax.bar(xvals, data, width=width, bottom=bottom, **props)
      bottom += data
    else:
      xvals = np.linspace(width * i, xmax + (width * i), N)
      ax.bar(xvals, data, width=width, **props)


    # Make patches for legend
    legend_handles.append(
        Patch(**props, label=f'Dataset {i}')
    )

  # Add legend
  leg = ax.legend(handles=legend_handles,
            bbox_to_anchor=(1, 1),
            labelspacing=1.8,
            bbox_transform=ax.transAxes)

  # make legend patches a little bit bigger
  for patch in leg.get_patches():
    patch.set_height(22)
    patch.set_y(-10)


patterned_bars_v2(10, num_sets=10, stacked=True, alpha=0.6)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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