Giter Site home page Giter Site logo

gyli / pywaffle Goto Github PK

View Code? Open in Web Editor NEW
575.0 9.0 104.0 3.32 MB

๐Ÿง‡ Make Waffle Charts in Python.

License: MIT License

Python 87.43% Shell 0.44% Jupyter Notebook 12.13%
python waffle charts matplotlib visualization data-visualization waffle-charts

pywaffle's Issues

Fractional blocks

Is there a way to enable fractional blocks, so that there is no rounding? I'm especially running into issues where the rounding causes the total number of blocks to fluctuate, as in the example below. Both datasets total to 87.46 but the top plot has an extra block. It'd be great if the last block could have fractional size, and if the intermediate blocks could have split colors.

output

Code to reproduce:

plot1 = {'Net income': 18.46, 'Income tax': 1.64, 'MG&A': 7.52, 'R&D': 15.3, 'Cost of sales': 44.54}
plot2 = {'Misc income': 1.2, 'Revenue': 86.26}
fig = plt.figure(
    FigureClass=Waffle,
    plots={
        311: {'values':plot1},
        312: {'values':plot2}
    },
    rows=5,
    figsize=(9, 7),
    legend={'loc': 'upper left', 'bbox_to_anchor': (1.1, 1)},
    block_arranging_style='snake',
)

Feature request

Great package! Are we able to get an option to change the square or dot to a custom graphic? For instance if it's a viz about humans, can we put a human svg icon from say font awesome and put it in there?

Ed

KeyError: 'rows' in waffle.py

Hi,
I tried your last example Multiple plot and had the following error

figsize=(9, 5) # figsize is a parameter of plt.figure
File "/usr/local/lib/python3.6/dist-packages/matplotlib/pyplot.py", line 533, in figure
**kwargs)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/backend_bases.py", line 160, in new_figure_manager
fig = fig_cls(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/pywaffle/waffle.py", line 165, in init
self._waffle(loc, **copy.deepcopy(setting))
File "/usr/local/lib/python3.6/dist-packages/pywaffle/waffle.py", line 174, in _waffle
if len(self._pa['values']) == 0 or not self._pa['rows']:
KeyError: 'rows'

Font awesome license

I notice that files from the Font Awesome project are being used. The project's license requires attribution. IANAL, and I am not affiliated with that project, but I think there probably needs to be a license file for these files, and this needs to be in the MANIFEST.in file (see #18) so it is included in sdists.

UserWarning: This figure includes Axes that are not compatible with tight_layout

First of all, incredibly awesome and fun package. Thanks a lot!

I'm getting this warning in all the plots:

UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect. warnings.warn("This figure includes Axes that are not compatible ").

It seems a false positive in this context, right?

Add Font Awesome through Python package

Font Awesome v6 now provides Python package on Pypi https://pypi.org/project/fontawesomefree/#description

Add Font Awesome through Python package, so no need to add a copy of otf files in PyWaffle.

This solution might not reduce the content that need to be downloaded when installing, and is not able to use system's font first (#25), while it does avoid some unnecessary downloads when there are other Python packages also using Font Awesome.

Request: ability to use system-packaged Fontawesome if found?

In Fedora, we have FontAwesome as an included package, and our packaging guidelines require bundled fonts to be ... debundled.

I've patched this in to my package build scripts (see https://mattdm.org/misc/fedora/pywaffle/python-pywaffle.spec), but it would be ideal if the library just noticed and used those. I guess this could be a "build time" thing, but I'm thinking maybe if

/usr/share/fonts/fontawesome5-free-fonts/Font Awesome 5 Free-Regular-400.otf
/usr/share/fonts/fontawesome5-free-fonts/Font Awesome 5 Free-Solid-900.otf
/usr/share/fonts/fontawesome5-brands-fonts/Font Awesome 5 Brands-Regular-400.otf

are installed, those could be automatically used -- with the mappings created at runtime from /usr/share/fontawesome5/metadata/icons.json.

That'd also benefit people who install via pip or whatever.

What do you think?

Font file not found when using FontAwesome icons

When creating a chart with icons a FileNotFoundError is thrown, whilst looking for the file font/FontAwesome.otf. This seems to be because it's trying to find the file relative to the location of the calling script, rather than in the font package created during installation.

A simple fix for this would be to modify waffle.py to import the font package and use its __path__ value to construct the path to the FontAwesome file:

import font
import os
FONTAWESOME_FILE = os.path.join(font.__path__[0], 'FontAwesome.otf')

If you're happy with this fix I can make a pull request.

block present when value is 0

Hi! Thanks for creating PyWaffle and the useful examples.

I started using it today and everything is great, except that sometimes I have a value of 0 for some items. But when the waffle chart is generated, a block is still present for the category with a value of 0.
Screen Shot 2019-08-30 at 4 53 12 PM

Could you look into making it so that there is no block for a label if the value is 0?

Problem with Font awesome on VsCode

I have a strange problem with the PyWaffle library. I am running the examples and everything is working fine except the examples with fontawesome.

I am running the following code and the result shows distorted picture.

dict_users = {'Regular': 62, 'New': 20, 'Churned': 16, 'Suspended': 2}
df = pd.Series(dict_users)
colors_list = ['slateblue', 'limegreen', 'red', 'grey']
colors = {df.index[i]:colors_list[i] for i in range(len(df))}
fig = plt.figure(FigureClass=Waffle,
                 figsize=(10,5),
                 values=dict_users,
                 rows=10,
                 colors=list(colors.values()),
                 icons=['user','user-plus', 'user-minus', 'user-clock'],
                 font_size=15,
                 icon_legend=True,
                 legend={'bbox_to_anchor': (1.55, 1), 'fontsize': 15, 'frameon': False})              
plt.title('User dynamics in July 2021', fontsize=20)
plt.show()

I am also having the the following warning message : IPython\core\pylabtools.py:151: UserWarning: Tight layout not applied. The bottom and top margins cannot be made large enough to accommodate all axes decorations.
fig.canvas.print_figure(bytes_io, **kw)

I also tried to use the command fig.set_tight_layout(False)
but the warning message did not go away.

output

Feature request

Great package! Are we able to get an option to change the square or dot to a custom graphic? For instance if it's a viz about humans, can we put a human svg icon from say font awesome and put it in there?

Ed

characters argument and plt.savefig

There seem to be a problem when saving figures as pdf with matplotlib.pyplot.savefig and using the characters argument in Waffle: some characters are replaced by others.

list_character = ["๐Ÿ–ณ", "๐Ÿ"]

from pywaffle import Waffle
from matplotlib import pyplot as plt

n_row = 4
n_column = 5

import numpy as np
list_value = np.ones(len(list_character))

fig = plt.figure(
    FigureClass=Waffle,
    rows=1,
    columns=len(list_character),
    values=list_value,
    characters=list_character,
    font_file="~/.fonts/Symbola.ttf",
    font_size=50
    )

plt.savefig("replaced_character.pdf")
plt.close("all")

yields the attached file (two snakes instead of a computer and a snake).
The computer alone is correctly printed. Inverting the order yields two snakes.

replaced_character.pdf

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

When using a pandas DataFrame, I keep getting this error, no matter what DataFrame I use:

Traceback (most recent call last):
  File "clean_input_file.py", line 177, in <module>
    main()
  File "clean_input_file.py", line 172, in main
    plot_res(data_FSW)
  File "clean_input_file.py", line 149, in plot_res
    title={'label': 'Vote Percentage in 2016 US Presidential Election', 'loc': 'left'}
  File "C:\Users\Pez Amaury\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\pyplot.py", line 548, in figure
    **kwargs)
  File "C:\Users\Pez Amaury\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backend_bases.py", line 160, in new_figure_manager
    fig = fig_cls(*args, **kwargs)
  File "C:\Users\Pez Amaury\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pywaffle\waffle.py", line 158, in __init__
    if (not self.fig_args['values'] or not self.fig_args['rows']) and not self.plots:
  File "C:\Users\Pez Amaury\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas\core\generic.py", line 1573, in __nonzero__
    .format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

I understand this is due to using operators or/and in waffle.py, so changing them to np.logical_and and np.logical_or would probably solve the problem.

Here's the dataFrame I'm using:

Variables
ART last 12 months 0.0
Access to condoms last 12 months 0.0
Any STI treatment last 12 months 0.0
Clean needles/syringes at last injection 0.0
Condom use at last time they had sex 0.0
Condom use when had anal sex last time with a male partner 0.0
Condom use when had sex last time with a commercial client 0.0
HBV Prevalence 0.0
HCV Prevalence 0.0
HIV Prevalence 0.0
HIV incidence 0.0
HIV test history 0.0
HIV test in last 12 months 0.0
HIV-1 Prevalence 0.0
HIV-2 Prevalence 0.0
OST/MMT last 6 months 0.0
Other STI Prevalence 0.0
Received HIV test results 0.0
STI test last 12 months 0.0
Syphilis Prevalence 0.0
Name: 2001, dtype: float64

Update to FontAwesome v5

Hello,

Thanks for creating this module, it's really useful and pretty straightforward to use.

One thing I've noticed is that the module currently uses FontAwesome v4.7.0, with the latest version of FA being v5.5.0. It'd be nice to be able to use the latest set of icons and updating the equivalence should be relatively straightforward through the cheatsheet they provide, but the download is now (I believe since 5.0) split into three .otf files - "solid", "regular" and "brands". I see there being two ways to deal with this:

  1. Pick one of the new three to have as the main reference. The "regular" is I think meant to be the most similar to the old icons, but the "solid" is the most complete.
  2. Keep all three and either:
    1. Add an extra parameter to choose which of the three icon sets to use (e.g. icon_set as a string).
    2. Rename the icon lookups to include which set they come from, and ensure the user only uses icons from one set.

I am happy to work on a PR for this based on your preference. I think 2i would work best (and might start looking at implementing it), but will defer to your judgement. There may also be some compatibility issues with name changes, but I think it's worth it for the wider set of icons available.

Thanks,

Adam

cant specify columns

Each chart I create (python 3.7.4, PyWaffle 0.2.3) is coming out square regardless of what is passed in the columns parameter. Its as if the columns parameter is being overwritten by what is passed to rows

    plt.figure(
        FigureClass=Waffle,
        rows=5,
        columns=10,
        values=[150, 75, 25],
        figsize=(16, 9)
    );
    plt.savefig('example.png')

example

missing corner squares with automatic scaling

I'm making 50ร—20 grids, so each block is 0.1%. I've found that with some data, the top right corner ends up empty. Here's a real-world example:

#!/usr/bin/python3

import matplotlib as m
m.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.dates as dates
from pywaffle import Waffle

m.style.use('seaborn-whitegrid')
m.rcParams['font.size'] = 12

fig = plt.figure( 
FigureClass=Waffle, 
 rows=20,
 columns=50,
 values={'32': 192,'33': 76,'34':59},
 figsize=[16, 9],
)              

fig.savefig('test.png',dpi=300)

            
plt.close()   

This results in:

test

... with an empty square in the top right -- a total of 999 squares instead of 1000.

I assume this is because all values are getting rounded down.

width problems with a thousand blocks

When plotting a larger number of blocks, the width of the white space between them become unstable:

plt.figure(
    FigureClass=Waffle,
    rows=20,
    columns=80,
    values=[300, 700],
    figsize=(18, 10)
);
plt.savefig('example.png')

image

This is probably outside the original scope of the package and maybe should even be discouraged, but sometimes is useful to give the reader the impression of dealing with a large population. Feel free to close this issue.

How to arrange the filling order as from top to bottom when using new-line?

Hi. I want to use the new-line arrangement for my plot.

This is what's shown in the documentation.

fig = plt.figure(
FigureClass=Waffle,
columns=10,
values=[30, 16, 4],
block_arranging_style='new-line',
vertical=True
)

image

However, as you can see, for the orange ones, if they have to span multiple rows and cannot span multiple rows, the plot will try to fill out the last row first, leaving the top row of the category incomplete. Is there a way to reverse it so that within each category, the top rows get filled out first then the bottom rows and if multiple rows cannot be filled the last row will be incomplete instead of the first row.

Vertical orientation?

It would be interesting to be able to generate plots that were vertically orientated - i.e. rather than drawing the blocks column by column, they could be drawn row by row. I've got a basic working attempt at asongtoruin/pywaffle@e4d73b7 which adds the extra boolean kwarg vertical to do this, but I wasn't sure if this was functionality you think would be useful for the module.

For example, if we take the basic example from the examples folder:
fig = plt.figure(FigureClass=Waffle, rows=5, columns=10, values=[48, 46, 3])
this produces the following horizontal plot:
basic_horiz

If we change this to
fig = plt.figure(FigureClass=Waffle, rows=10, columns=5, values=[48, 46, 3], vertical=True)
we instead get a vertically oriented plot:

basic

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.