1
$\begingroup$

Given the dataset:

timestamp                     item       itemcount
2019-03-18 07:40:08.759        A          10
2019-03-18 08:40:08.759        B          5
..................................................
2019-05-20 07:40:08.759        D          4
2019-05-21 07:40:08.759        E          8

I want to plot stacked histogram like: stacked histogram

where the x-axis should be the date and y axis the itemcount and stack will be each item. I want the graph with subplots for every month.

I am new here so will be happy to get any feedback on my mistakes. Thank you.

here's one sample code i found online which plots the same graph in the figure above.

  # Import Data
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/mpg_ggplot2.csv")

# Prepare data
x_var = 'manufacturer'
groupby_var = 'class'
df_agg = df.loc[:, [x_var, groupby_var]].groupby(groupby_var)
vals = [df[x_var].values.tolist() for i, df in df_agg]

# Draw
plt.figure(figsize=(16,9), dpi= 80)
colors = [plt.cm.Spectral(i/float(len(vals)-1)) for i in range(len(vals))]
n, bins, patches = plt.hist(vals, df[x_var].unique().__len__(), stacked=True, density=False, color=colors[:len(vals)])

# Decoration
plt.legend({group:col for group, col in zip(np.unique(df[groupby_var]).tolist(), colors[:len(vals)])})
plt.title(f"Stacked Histogram of ${x_var}$ colored by ${groupby_var}$", fontsize=22)
plt.xlabel(x_var)
plt.ylabel("Frequency")
plt.ylim(0, 40)
plt.xticks(ticks=bins, labels=np.unique(df[x_var]).tolist(), rotation=90, horizontalalignment='left')
plt.show()
$\endgroup$
6
  • $\begingroup$ Can you include the necessary information and tags on your used framework/language and your code tried so far? (e.g. R & ggplot vs. Python & seaborn or matplotlib or...) $\endgroup$
    – Fnguyen
    Commented Sep 26, 2019 at 11:10
  • $\begingroup$ any library or framework is okay for me. I tried using matplotlib but was not able to do it. $\endgroup$
    – naman
    Commented Sep 26, 2019 at 12:44
  • $\begingroup$ so I can assume you use Python? (I'd add that to the question and tags because an R answer is unlikely to get you to your goal then). Can you show the matplotlibe code you tried so far, it may be easier to fix that instead of starting from 0. $\endgroup$
    – Fnguyen
    Commented Sep 26, 2019 at 12:50
  • $\begingroup$ yeah... I have no idea on how to plot this kind of graph. I have this dataset and wanted to plot a similar graph and found one online. $\endgroup$
    – naman
    Commented Sep 26, 2019 at 15:49
  • $\begingroup$ I have edited my question with the code $\endgroup$
    – naman
    Commented Sep 26, 2019 at 15:51

2 Answers 2

0
$\begingroup$

This solution uses plotnine which is based on R ggplot and the grammar of graphics.

Generally you have to transform the timestamp to months first and then understand that:

X = Months Y = itemcount Group = item

This should help also for your matplotlib solution!

from datetime import datetime
import pandas as pd
from plotnine import *

df['month'] = pd.DatetimeIndex(df['timestamp']).month

p = (ggplot(pdf, aes(x = 'month', y = 'itemcount',fill='item')) + geom_bar( Star = 'identity',position='fill')

# fill here acts the same as group in matplotlib
```
$\endgroup$
5
  • $\begingroup$ getting an error msg as: stat_count() must not be used with a y aesthetic $\endgroup$
    – naman
    Commented Sep 28, 2019 at 20:19
  • $\begingroup$ @naman use stat = 'identity' in the geom_bar function. $\endgroup$
    – Fnguyen
    Commented Sep 29, 2019 at 16:13
  • $\begingroup$ thank you for your solution. $\endgroup$
    – naman
    Commented Oct 3, 2019 at 9:18
  • $\begingroup$ Can you suggest me how I can plot subplots for every month. I will take x as day. @Fnguyen $\endgroup$
    – naman
    Commented Oct 3, 2019 at 10:04
  • $\begingroup$ @naman you should really post a new question with reproducible sample data. $\endgroup$
    – Fnguyen
    Commented Oct 3, 2019 at 11:30
0
$\begingroup$

You may apply Wolfram Language to your project. There is a free Wolfram Engine for developers you can download and with the Wolfram Client Library for Python you can use these functions in Python.

You may use the DateHistogram function for your plot. However, lets create an example data set in Python first.

import pandas as pd
import random
from datetime import datetime, timedelta

start_date = datetime(2019, 9, 27)
end_date = start_date + timedelta(days=365)

random.seed(91827364)

data = {
        'timestamp' : list(map(
                                lambda r: start_date + (end_date - start_date) * r, 
                                [random.random() for i in range(100)]
                            )),
        'item' : random.choices(['A','B','C','D','E','F'], k=100),
        'itemcount' : [random.randrange(1,20) for i in range(100)]
       }

dfTimes = pd.DataFrame.from_dict(data)

dfTimes.head()

Mathematica graphics

Using DateHistogram and WeightedData on dfTimes the plot can be generated.

from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr

wolfSession = WolframLanguageSession()

dh = wolfSession.evaluate(
    wl.DateHistogram(
        wl.Query(
            wl.RightComposition(wl.GroupBy(wlexpr('#["item"]&')), wl.KeySort), 
            wl.RightComposition(wl.Values, wl.Transpose, wl.Apply(wl.WeightedData)),
            wl.RightComposition(['timestamp', 'itemcount'], wl.Values)
        )(dfTimes),
        'Month', 'Count',
        PlotLabel='Sum(Item Count)',
        ChartLayout="Stacked",
        ChartLegends=wl.Automatic,
        DateTicksFormat=['MonthNameShort',' ','YearShort'],
        ImageSize=wl.Large,
        ChartBaseStyle=wl.Opacity(1),
        ChartStyle=wl.ColorData(["Indexed","Sunrise"])
    )
)

Mathematica graphics

wolfSession.terminate()

If you environment does not render dh then you can view the chart by Exporting in one of the supported Raster Image Formats or Vector Graphics Formats.

wolfSession.evaluate(
    wl.Export(
        '<path with image filename>', 
        dh
        )
    )
)

In Wolfram Language with a Dataset dfTimes containing the same data then, for comparison, the same chart is (Dataset gets a bit of syntax sugar with Query).

DateHistogram[
 dfTimes[
  GroupBy[#["item"] &] /* KeySort,
  Values /* Transpose /* Apply[WeightedData],
  {"timestamp", "itemcount"} /* Values
  ],
 "Month", "Count",
 PlotLabel -> "Sum(Item Count)",
 ChartLayout -> "Stacked",
 ChartLegends -> Automatic,
 DateTicksFormat -> {"MonthNameShort", " ", "YearShort"},
 ImageSize -> Large,
 ChartBaseStyle -> Opacity[1],
 ChartStyle -> ColorData[{"Indexed", "Sunrise"}]]

Hope this helps.

$\endgroup$
2
  • $\begingroup$ Thank you for the solution. Tried the solution. But got stuck into many errors as: ''WolframKernelException: Cannot locate a kernel automatically. Please provide an explicit kernel path" $\endgroup$
    – naman
    Commented Sep 28, 2019 at 20:21
  • $\begingroup$ @naman You must download the free Wolfram Engine. $\endgroup$
    – Edmund
    Commented Sep 28, 2019 at 21:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.