0

I guess this is a simple question, but I've been trying for hours with no results. I have a dict that I want to see in a chart in matplotlib

  • At this time I'm only using the values of the dict, the keys will be used latter.
  • The values are lists of tuples, each tuple is a pair of a date and a number.
  • The lists have different lengths, and, within them, the dates have different starts and ends, and all time frames are progressive but with no sequence.
  • The dict can vary because is generated by the user, but it will have the same structure.
  • I want to create a chart with as many lines as the length of the dict.
  • XAxis with numbers and YAxis with dates
_mat_graph =
{'AFG': [(datetime.datetime(2021, 2, 22, 0, 0), 0.0),
         (datetime.datetime(2021, 2, 28, 0, 0), 8200.0),
         (datetime.datetime(2021, 3, 16, 0, 0), 54000.0),
         (datetime.datetime(2021, 4, 7, 0, 0), 120000.0),
         (datetime.datetime(2021, 4, 22, 0, 0), 240000.0),
         (datetime.datetime(2021, 5, 11, 0, 0), 448878.0)]
 'ALB': [(datetime.datetime(2021, 1, 10, 0, 0), 0.0),
         (datetime.datetime(2021, 1, 12, 0, 0), 128.0),
         (datetime.datetime(2021, 1, 13, 0, 0), 188.0),
         (datetime.datetime(2021, 1, 14, 0, 0), 266.0),
         (datetime.datetime(2021, 1, 15, 0, 0), 308.0),
         (datetime.datetime(2021, 1, 16, 0, 0), 369.0),
         (datetime.datetime(2021, 1, 17, 0, 0), 405.0),
         (datetime.datetime(2021, 1, 18, 0, 0), 447.0),
         (datetime.datetime(2021, 1, 19, 0, 0), 483.0),
         (datetime.datetime(2021, 1, 20, 0, 0), 519.0),
         (datetime.datetime(2021, 1, 21, 0, 0), 549.0),
         (datetime.datetime(2021, 2, 2, 0, 0), 549.0),
         (datetime.datetime(2021, 2, 9, 0, 0), 689.0),
         (datetime.datetime(2021, 2, 17, 0, 0), 1090.0),
         (datetime.datetime(2021, 2, 18, 0, 0), 2438.0),
         (datetime.datetime(2021, 2, 22, 0, 0), 6073.0),
         (datetime.datetime(2021, 5, 11, 0, 0), 440921.0),
         (datetime.datetime(2021, 5, 12, 0, 0), 444755.0),
         (datetime.datetime(2021, 5, 13, 0, 0), 445402.0),
         (datetime.datetime(2021, 5, 14, 0, 0), 448571.0)]
 'AND': [(datetime.datetime(2021, 1, 25, 0, 0), 576.0),
         (datetime.datetime(2021, 2, 1, 0, 0), 1036.0),
         (datetime.datetime(2021, 2, 10, 0, 0), 1291.0),
         (datetime.datetime(2021, 2, 12, 0, 0), 1622.0),
         (datetime.datetime(2021, 2, 19, 0, 0), 2141.0),
         (datetime.datetime(2021, 2, 24, 0, 0), 2390.0),
         (datetime.datetime(2021, 3, 8, 0, 0), 2439.0),
         (datetime.datetime(2021, 3, 10, 0, 0), 3650.0),
         (datetime.datetime(2021, 3, 15, 0, 0), 7098.0),
         (datetime.datetime(2021, 4, 5, 0, 0), 9781.0),
         (datetime.datetime(2021, 4, 19, 0, 0), 21733.0),
         (datetime.datetime(2021, 4, 26, 0, 0), 23822.0),
         (datetime.datetime(2021, 5, 3, 0, 0), 24182.0),
         (datetime.datetime(2021, 5, 10, 0, 0), 26931.0)]}

Now, this is the (not working...) code I'm using (SAFE_COLORS is a dict of lists of rgb colors in hex):

from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from matplotlib.dates import drange
import numpy as np

cont = 0
for _iso, _entries in _mat_graph.items():
    graph_dates = drange(_entries[0][0], _entries[-1][0], timedelta(days=1))
    cantidades = np.array([x[1] for x in _entries])
    plt.plot_date(
        graph_dates,
        cantidades,
        color=SAFE_COLORS[12][cont],
        marker='.'
    )
    cont += 1
plt.show()

And this is the error I get:

path\to\pyfiles\main.py:1055: UserWarning: marker is redundantly defined by the 'marker' keyword argument and the fmt string "o" (-> marker='o'). The keyword argument will take precedence.
  plt.plot_date(
Traceback (most recent call last):
  File "path\to\pyfiles\main.py", line 1055, in <module> plt.plot_date(
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\pyplot.py", line 3029, in plot_date
    return gca().plot_date(
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\__init__.py", line 1361, in inner
    return func(ax, *map(sanitize_sequence, args), **kwargs)
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\axes\_axes.py", line 1676, in plot_date
    return self.plot(x, y, fmt, **kwargs)
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\axes\_axes.py", line 1605, in plot
    lines = [*self._get_lines(*args, data=data, **kwargs)]
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\axes\_base.py", line 315, in __call__
    yield from self._plot_args(this, kwargs)
  File "path\to\pyfiles\.venv\lib\site-packages\matplotlib\axes\_base.py", line 501, in _plot_args
    raise ValueError(f"x and y must have same first dimension, but "
ValueError: x and y must have same first dimension, but have shapes (78,) and (6,)

Any help will be appreciated, thanks in advance,

2
  • 1
    You'll need to say what you would like to happen. Try to describe the chart what you one to produce. What kind, what will be on the x and y axis, how many etc. Also edit your question to describe what happens when you try your current approach and why this is inadequate. Commented May 19, 2021 at 18:26
  • Thanks @Jason, done. Commented May 19, 2021 at 18:52

1 Answer 1

2

I'm not exactly sure what you are trying to do with the graph_dates above, but my guess is that is your problem. Simplest is:

fig, ax = plt.subplots(constrained_layout=True)
plt.rcParams['date.converter'] = 'concise'
for key, data in _mat_graph.items():
    date = [x[0] for x in data]
    data = [x[1] for x in data]
    ax.plot(date, data, '.', ms=10, label=key)
ax.legend()
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Jody it worked perfectly!, just, any ideas on how to give date format (something like '%Y-%m%d') to the y axis values?
found it, import matplotlib.dates as mdates | ax.xaxis.set_major_formatter(mdates.DateFormatter('%b\n%d'))

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.