plotly-calplot
Advanced tools
+3
-1
| Metadata-Version: 2.1 | ||
| Name: plotly-calplot | ||
| Version: 0.1.13 | ||
| Version: 0.1.16 | ||
| Summary: Calendar Plot made with Plotly | ||
@@ -14,2 +14,4 @@ Home-page: https://github.com/brunorosilva/plotly-calplot | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Requires-Dist: numpy (>=1.22.3,<2.0.0) | ||
@@ -16,0 +18,0 @@ Requires-Dist: pandas (>=1.0.5,<2.0.0) |
| from datetime import date | ||
| from typing import Any, Dict, Optional | ||
| import numpy as np | ||
| from pandas import DataFrame, Grouper, Series | ||
@@ -71,2 +72,7 @@ from plotly import graph_objects as go | ||
| text: Optional[str] = None, | ||
| years_as_columns: bool = False, | ||
| cmap_min: Optional[float] = None, | ||
| cmap_max: Optional[float] = None, | ||
| start_month: int = 1, | ||
| end_month: int = 12, | ||
| ) -> go.Figure: | ||
@@ -123,11 +129,26 @@ """ | ||
| space_between_plots: float = 0.08 | ||
| space_between_plots : float = 0.08 | ||
| controls the vertical space between the plots | ||
| showscale: bool = False | ||
| showscale : bool = False | ||
| if True, a color legend will be created. | ||
| Thanks to @ghhar98! | ||
| text: Optional[str] = None | ||
| text : Optional[str] = None | ||
| The name of the column in data to include in hovertext. | ||
| years_as_columns : bool = False | ||
| if True will plot all years in a single line | ||
| cmap_min : float = None | ||
| colomap min, defaults to min value of the data | ||
| cmap_max : float = None | ||
| colomap max, defaults to max value of the data | ||
| start_month : int = 1 | ||
| starting month range to plot, defaults to 1 (January) | ||
| end_month : int = 12 | ||
| ending month range to plot, defaults to 12 (December) | ||
| """ | ||
@@ -141,15 +162,39 @@ unique_years = data[x].dt.year.unique() | ||
| # single row calplot logic | ||
| if years_as_columns: | ||
| rows = 1 | ||
| cols = unique_years_amount | ||
| else: | ||
| rows = unique_years_amount | ||
| cols = 1 | ||
| # if single row calplot, the height can be constant | ||
| if total_height is None: | ||
| total_height = 150 * unique_years_amount | ||
| if years_as_columns: | ||
| total_height = 150 | ||
| else: | ||
| total_height = 150 * unique_years_amount | ||
| fig = make_subplots( | ||
| unique_years_amount, | ||
| 1, | ||
| rows=rows, | ||
| cols=cols, | ||
| subplot_titles=subplot_titles, | ||
| vertical_spacing=space_between_plots, | ||
| ) | ||
| # getting cmap_min and cmap_max | ||
| if cmap_min is None: | ||
| cmap_min = data[y].min() | ||
| if cmap_max is None: | ||
| cmap_max = data[y].max() | ||
| data = data[ | ||
| data[x].dt.month.isin(np.arange(start_month, end_month + 1, 1).tolist()) | ||
| ] | ||
| for i, year in enumerate(unique_years): | ||
| selected_year_data = data.loc[data[x].dt.year == year] | ||
| selected_year_data = fill_empty_with_zeros( | ||
| selected_year_data, x, dark_theme, year | ||
| selected_year_data, x, year, start_month, end_month | ||
| ) | ||
@@ -175,5 +220,8 @@ | ||
| text_name=text, | ||
| years_as_columns=years_as_columns, | ||
| start_month=start_month, | ||
| end_month=end_month, | ||
| ) | ||
| fig = apply_general_colorscaling(data, y, fig) | ||
| fig = apply_general_colorscaling(fig, cmap_min, cmap_max) | ||
| if showscale: | ||
@@ -180,0 +228,0 @@ fig = showscale_of_heatmaps(fig) |
@@ -7,8 +7,17 @@ from typing import Any, List, Tuple | ||
| def get_month_names(data: pd.DataFrame, x: str) -> List[str]: | ||
| return list(data[x].dt.month_name().unique()) | ||
| def get_month_names( | ||
| data: pd.DataFrame, x: str, start_month: int = 1, end_month: int = 12 | ||
| ) -> List[str]: | ||
| start_month_names_filler = [None] * (start_month - 1) | ||
| end_month_names_filler = [None] * (12 - end_month) | ||
| month_names = list( | ||
| start_month_names_filler | ||
| + data[x].dt.month_name().unique().tolist() | ||
| + end_month_names_filler | ||
| ) | ||
| return month_names | ||
| def get_date_coordinates( | ||
| data: pd.DataFrame, x: str | ||
| data: pd.DataFrame, x: str, start_month: int, end_month: int | ||
| ) -> Tuple[Any, List[float], List[int]]: | ||
@@ -19,3 +28,3 @@ month_days = [] | ||
| month_positions = (np.cumsum(month_days) - 15) / 7 | ||
| month_positions = np.linspace(1.5, 50, 12) | ||
| weekdays_in_year = [i.weekday() for i in data[x]] | ||
@@ -22,0 +31,0 @@ |
@@ -100,2 +100,3 @@ from typing import Any, List, Optional | ||
| total_height: Optional[int], | ||
| years_as_columns: bool, | ||
| ) -> go.Figure: | ||
@@ -106,8 +107,18 @@ fig.update_layout(layout) | ||
| fig.update_layout(height=total_height) | ||
| fig.add_traces(cplt, rows=[(row + 1)] * len(cplt), cols=[1] * len(cplt)) | ||
| if years_as_columns: | ||
| rows = [1] * len(cplt) | ||
| cols = [(row + 1)] * len(cplt) | ||
| else: | ||
| rows = [(row + 1)] * len(cplt) | ||
| cols = [1] * len(cplt) | ||
| fig.add_traces(cplt, rows=rows, cols=cols) | ||
| return fig | ||
| def apply_general_colorscaling(data: pd.DataFrame, y: str, fig: go.Figure) -> go.Figure: | ||
| return fig.update_traces(selector=dict(type="heatmap"), zmax=data[y].max(), zmin=0) | ||
| def apply_general_colorscaling( | ||
| fig: go.Figure, cmap_min: float, cmap_max: float | ||
| ) -> go.Figure: | ||
| return fig.update_traces( | ||
| selector=dict(type="heatmap"), zmax=cmap_max, zmin=cmap_min | ||
| ) | ||
@@ -114,0 +125,0 @@ |
@@ -33,2 +33,5 @@ from typing import List, Optional | ||
| text_name: Optional[str] = None, | ||
| years_as_columns: bool = False, | ||
| start_month: int = 1, | ||
| end_month: int = 12, | ||
| ) -> go.Figure: | ||
@@ -39,5 +42,5 @@ """ | ||
| month_names = get_month_names(data, x) | ||
| month_names = get_month_names(data, x, start_month, end_month) | ||
| month_positions, weekdays_in_year, weeknumber_of_dates = get_date_coordinates( | ||
| data, x | ||
| data, x, start_month, end_month | ||
| ) | ||
@@ -71,4 +74,6 @@ | ||
| layout = decide_layout(dark_theme, title, month_names, month_positions) | ||
| fig = update_plot_with_current_layout(fig, cplt, row, layout, total_height) | ||
| fig = update_plot_with_current_layout( | ||
| fig, cplt, row, layout, total_height, years_as_columns | ||
| ) | ||
| return fig |
@@ -1,2 +0,2 @@ | ||
| from datetime import date | ||
| from datetime import date, datetime, timedelta | ||
@@ -8,10 +8,16 @@ import pandas as pd | ||
| def fill_empty_with_zeros( | ||
| selected_year_data: DataFrame, x: str, dark_theme: bool, year: int | ||
| selected_year_data: DataFrame, | ||
| x: str, | ||
| year: int, | ||
| start_month: int, | ||
| end_month: int, | ||
| ) -> pd.DataFrame: | ||
| year_min_date = date(year=year, month=1, day=1) | ||
| year_max_date = date(year=year, month=12, day=31) | ||
| if end_month != 12: | ||
| last_date = datetime(year, end_month + 1, 1) + timedelta(days=-1) | ||
| else: | ||
| last_date = datetime(year, 1, 1) + timedelta(days=-1) | ||
| year_min_date = date(year=year, month=start_month, day=1) | ||
| year_max_date = date(year=year, month=end_month, day=last_date.day) | ||
| df = pd.DataFrame({x: pd.date_range(year_min_date, year_max_date)}) | ||
| final_df = df.merge(selected_year_data, how="left") | ||
| if not dark_theme: | ||
| final_df = final_df.fillna(0) | ||
| return final_df |
+1
-1
| [tool.poetry] | ||
| name = "plotly_calplot" | ||
| version = "0.1.13" | ||
| version = "0.1.16" | ||
| description = "Calendar Plot made with Plotly" | ||
@@ -5,0 +5,0 @@ authors = ["Bruno Rodrigues Silva <b.rosilva1@gmail.com>"] |
+3
-3
@@ -15,3 +15,3 @@ # -*- coding: utf-8 -*- | ||
| 'name': 'plotly-calplot', | ||
| 'version': '0.1.13', | ||
| 'version': '0.1.16', | ||
| 'description': 'Calendar Plot made with Plotly', | ||
@@ -21,4 +21,4 @@ 'long_description': '# Calendar Heatmap with Plotly\nMaking it easier to visualize and costumize time relevant or time series data with plotly interaction.\n\nNew to the library? Read [this Medium article](https://medium.com/@brunorosilva/5fc322125db7).\n\nThis plot is a very similar to the contribuitions available on Github and Gitlab profile pages and to [Calplot](https://github.com/tomkwok/calplot) - which is a pyplot implementation of the calendar heatmap, thus it is not interactive right off the bat.\n\nThe first mention I could find of this plot being made with plotly was in [this forum post](https://community.plotly.com/t/colored-calendar-heatmap-in-dash/10907/16) and it got my attention as something that should be easily available to anyone.\n\n# Installation\n``` bash\npip install plotly-calplot\n```\n\n# Examples\n\nIn [this Medium article](https://medium.com/@brunorosilva/5fc322125db7) I covered lot\'s of usage methods for this library.\n``` python\nfrom plotly_calplot import calplot\n\nfig = calplot(df, x="date", y="value")\nfig.show()\n# you can also adjust layout and your usual plotly stuff\n```\n\n<img src="https://github.com/brunorosilva/plotly-calplot/blob/main/assets/images/example.png?raw=true">\n', | ||
| 'author_email': 'b.rosilva1@gmail.com', | ||
| 'maintainer': None, | ||
| 'maintainer_email': None, | ||
| 'maintainer': 'None', | ||
| 'maintainer_email': 'None', | ||
| 'url': 'https://github.com/brunorosilva/plotly-calplot', | ||
@@ -25,0 +25,0 @@ 'packages': packages, |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
24366
10.41%581
13.48%