Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add axes.violinplot test from test_datetime.py #27521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

tanvincible
Copy link

@tanvincible tanvincible commented Dec 15, 2023

PR summary

This PR is modeled for #26864 Axes.violinplot.

Image of generated plot:

image

@tanvincible tanvincible marked this pull request as ready for review December 15, 2023 12:25
@ksunden
Copy link
Member

ksunden commented Dec 18, 2023

From #27485 (comment):

All that said, I am now curious if at least the positioning values (position and width) work as desired (with the latter being a timedelta). Because while doing statistics on dates can get strange fast (not impossible, just have to be careful about knowing what you are doing), saying "I want a violin plot comparing measurements taken on different dates" seems completely reasonable.

I think my leaning is to deprioritize fixing of units along the stats axis of these, but ask that this test case is written to focus on positions instead for the time being.

While I agree that the "primary" piece of violinplot generally doesn't make sense/doesn't work with dates, there is still a piece that should work (Though I admittedly haven't tested it)

@tanvincible
Copy link
Author

tanvincible commented Dec 19, 2023

@ksunden Not sure which "piece" you are talking about... Should I test again with width being a timedelta?
Unfortunately, keeping positions = date_timedeltas and widths = timedelta(days=5) didn't worked:

import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime, timedelta
from collections import defaultdict
import pytest
import matplotlib as mpl

@pytest.mark.xfail(reason="Test for violinplot not written yet")
@mpl.style.context("default")
class TestViolinPlot:

    def test_violinplot(self):
        np.random.seed(42)
        n_samples = 100
        dates_values = [(datetime(2023, 1, 1) + timedelta(days=np.random.randint(1, 15)), np.random.randn())
                        for _ in range(n_samples)]
        values_by_date = defaultdict(list)
        for date, value in dates_values:
            values_by_date[date.toordinal()].append(value)
        date_ordinals, values = zip(*values_by_date.items())
        date_timedeltas = [datetime.fromordinal(date) - datetime(2023, 1, 1) for date in date_ordinals]
        fig, ax = plt.subplots()
        result = ax.violinplot(values, positions=date_timedeltas, widths=timedelta(days=5), showmeans=True, showextrema=True)
        ax.set_title('Violin Plot with DateTime and Timedelta Positions')
        ax.set_xticks(date_timedeltas)
        ax.set_xticklabels([datetime.fromordinal(date).strftime('%Y-%m-%d')
                           for date in date_ordinals], rotation=45, ha='right')
        ax.set_xlabel('Dates')
        ax.set_ylabel('Values')
        assert result is not None, "Failed to create violin plot"

Pytest Output:

================================================= test session starts =================================================
platform win32 -- Python 3.11.5, pytest-7.4.3, pluggy-1.3.0
Matplotlib: 3.8.2
Freetype: 2.6.1
rootdir: C:\Users\XXXX
plugins: anyio-3.5.0, asdf-3.0.1, mpl-0.16.1
collected 1 item

XXXX\test_untitled2.py x                                                                             [100%]

================================================= 1 xfailed in 0.50s ==================================================

Edit: Corrected grammatical mistakes.

@tanvincible
Copy link
Author

Oops, I wrote the wrong test in the PR description. (The test gives an output (plus it doesn't deal with timedelta); my bad!)
Removed the test :)

@ksunden
Copy link
Member

ksunden commented Dec 19, 2023

positions is a datetime, widths is a timedelta:

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


np.random.seed(19680801)
n_samples = 100
values = np.random.randn(n_samples)
fig, ax = plt.subplots()
result = ax.violinplot(values, positions=[datetime(2023, 1, 10)], widths=[timedelta(days=10)], showmeans=True, showextrema=True)

Gives:

violin

This shows a plot that is centered on on a datetime and has a width given by the time delta.

It automatically sets the ticks and formatter for the X axis.

So it is demonstrating that units are adhered to by positions/width.

A more complete test would probably have multiple violins (possibly on the same Axes) with different widths/positions/etc.

While the values are not handed datetime values (in any sense) here, which is one way violin could have (but does not fully) supported units, the position and width (x-axis) values are supported.

@tanvincible tanvincible changed the title Remove axes.violinplot test from test_datetime.py Add axes.violinplot test from test_datetime.py Dec 20, 2023
@tanvincible
Copy link
Author

@ksunden Could you please review?

@tanvincible tanvincible closed this Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting for author
Development

Successfully merging this pull request may close these issues.

3 participants