Python Forum
How to do bar graph with positive and negative values different colors?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to do bar graph with positive and negative values different colors?
#1
I've been battling this one for over an hour so I'm going to ask for help.

I have a dataframe column that shows trade results. I want those less than zero to plot red and nonnegative values to plot green. I saw this on SO:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = np.arange(10) * 0.1

mask1 = y < 0.5
mask2 = y >= 0.5

plt.bar(x[mask1], y[mask1], color = 'red')
plt.bar(x[mask2], y[mask2], color = 'blue')
plt.show()
Here's my attempt:

plt.figure(figsize=(15, 10))
mask1 = summary_results['ROI%'] < 0
mask2 = summary_results['ROI%'] >= 0
plt.bar(summary_results.index,summary_results['ROI%'][mask1],color = 'r')
plt.bar(summary_results.index,summary_results['ROI%'][mask2],color = 'g')
plt.grid()
plt.show()
This gives ValueError: shape mismatch: objects cannot be broadcast to a single shape .

I think the problem is the number of values either negative or nonnegative are less than the number of total values, which is conveyed by summary_results.index. I'm really not sure what to do with the x-argument. I don't really want to bring the whole index in using this approach--just the index values corresponding to the negative or nonnegative ROI% values, accordingly, as the position for the bar to be plot.

Really, I just want to go down the summary_results['ROI%'] column and plot a bar for each value. I originally thought default would be left to right, but that gave TypeError with one positional argument missing.

Another way I thought of doing this was to have color = colors where colors is a list of 'r' and 'g' depending on whether summary_results['ROI%'] is negative or nonnegative. Seems like I could do this with a list comprehension, but I'm not quite sure how to do it. I can't say if summary_results['ROI%'] < 0 because summary_results['ROI%'] is a dataframe column (Series?) and it doesn't make sense to evaluate a whole series against one value. I really mean to iterate down the series and evaluate each value. So maybe this could be done with a for loop?

colors = []
for i in summary_results['ROI%']:
    if i < 0:
        colors.append('r')
    else:
        colors.append('g')
This could work, but it seemed like the list comprehension would be simpler.

And the mask idea seems nifty... any way to make that work?
Reply
#2
This works for the mask approach:
plt.figure(figsize=(15, 10))
mask1 = summary_results['ROI%'] < 0
mask2 = summary_results['ROI%'] >= 0
plt.bar(summary_results.index[mask1],summary_results['ROI%'][mask1],color = 'r')
plt.bar(summary_results.index[mask2],summary_results['ROI%'][mask2],color = 'g')
plt.grid()
plt.show()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  negative memory usage akbarza 1 44 1 hour ago
Last Post: Gribouillis
  Count image's colors very fast flash77 18 1,587 Mar-05-2024, 06:12 PM
Last Post: deanhystad
  can openpyxl read font colors mperemsky 3 1,754 May-09-2023, 11:18 AM
Last Post: MindKeeper
  Positive integral solutions for Linear Diophantine Equation august 4 1,243 Jan-13-2023, 09:48 PM
Last Post: Gribouillis
  ANSI not working for change of text colors BliepMonster 10 3,418 Nov-10-2022, 09:28 AM
Last Post: BliepMonster
  function accepts infinite parameters and returns a graph with those values edencthompson 0 868 Jun-10-2022, 03:42 PM
Last Post: edencthompson
  is there any tool to convert negative base to int? Skaperen 7 2,419 May-27-2022, 07:30 AM
Last Post: Gribouillis
  Regex: positive lookbehind Secret 2 2,009 Sep-21-2020, 12:59 AM
Last Post: snippsat
  Plot Back Ground Colors JoeDainton123 0 2,197 Aug-19-2020, 11:09 PM
Last Post: JoeDainton123
  How to fill between the same area with two different colors Staph 0 1,495 Jul-08-2020, 07:01 PM
Last Post: Staph

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020