How to add data table into legend in openpyxl - openpyxl

How to use openpyxl to add data table into legend area like the pic show below:
There is a openpyxl.chart.chartspace.DataTable class in openpyxl, but I can't find any examples to use it.

Maybe it's too late, but if someone needs it, I've found a solution.
from openpyxl import Workbook
from openpyxl.chart import BarChart, Series, Reference
from openpyxl.chart.plotarea import DataTable
# Create a new Workbook.
wb = Workbook()
# Select the active worksheet.
ws = wb.active
# Data
rows = [
('val', 'Batch 1', 'Batch 2'),
('val_1', 10, 30),
('val_2', 40, 60),
('val_3', 50, 70),
('val_4', 20, 10),
('val_5', 10, 40),
('val_6', 50, 30),
]
# Adding data to worksheet.
for row in rows:
ws.append(row)
# Create a new BarChart.
chart1 = BarChart()
# Adding some attributes.
chart1.type = "col"
chart1.style = 3
chart1.title = "Bar Chart"
chart1.y_axis.title = 'Test number'
chart1.x_axis.title = 'Sample length (mm)'
# Adding data and labels.
data = Reference(ws, min_col=2, min_row=1, max_row=7, max_col=3)
labels = Reference(ws, min_col=1, min_row=2, max_row=7)
chart1.add_data(data, titles_from_data=True)
chart1.set_categories(labels)
chart1.shape = 4
# --- SOLUTION --- Creating the legend table.
chart1.plot_area.dTable = DataTable()
chart1.plot_area.dTable.showHorzBorder = True
chart1.plot_area.dTable.showVertBorder = True
chart1.plot_area.dTable.showOutline = True
chart1.plot_area.dTable.showKeys = True
ws.add_chart(chart1, "A10")
wb.save(".\\result.xlsx")
--- RESULT ---
openpyxl version == 3.0.10
I hope I've been able to help! :D

Related

Data Preparation of a given .CSV

test_sales
I would like to get a new data_set with the following column structure:
#the structure of the task [new csv]
1) order_number
2) number_of_orders_past_3_months
3) gross_sum_orders_past_3_months
4) number_of_orders_future_3_months
5) gross_sum_orders_future_3_months
# The produced data frame should be unique by order number.
I have done the following but I am not sure if it is right:
df1 = pd.read_csv('test_sales')
df2 = df1.to_csv('order_count_sum.csv')
df2 = pd.read_csv('order_count_sum.csv')
df2['order_datetime'] = pd.to_datetime(df2['order_datetime'])
df2['number_of_orders_past_3_months'] = df2.groupby('order_number')['order_number'].value_counts().reset_index(drop = True)
df2['gross_sum_orders_past_3_months'] = df2.groupby(['order_number']).rolling(3, min_periods = 1, on = 'order_datetime')['gross_value'].sum().reset_index( drop = True)
df2.head(20)
the new .csv
May I know how can I get the following:
number_of_orders_future_3_months
gross_sum_orders_future_3_months

ExcelWriter format number to currency by column name

I'm converting the float columns to currency data type with the following:
df = pd.DataFrame({'col0': [71513.0, 200000.0, None],
'col1': [True, False, False],
'col2': [100.0, 200.0, 0.0]})
df[['col0', 'col2']] = df[['col0', 'col2']].astype(float).astype("Int32").applymap(\
lambda x: "${:,.0f}".format(x) if isinstance(x, int) else x)
I am outputting the table with the following:
writer = pd.ExcelWriter('output.xlsx', engine='xlsxwriter')
df.to_excel(writer, index= False)
workbook = writer.book
ws = writer.sheets['Sheet1']
writer.close()
writer.save()
However, when I output the datable with the following, the currency is stored as text:
How would I format the excel sheet itself (instead of the pandas column) based on the column name so that the value is a number, but the formatting is currency?
This is how it worked for me
Removed the column formatting within df
df = pd.DataFrame({'col0': [71513.0, 200000.0, None],
'col1': [True, False, False],
'col2': [100.0, 200.0, 0.0]})
Removed index parameter from to_excel,
Defined format for the columns, and assign it to columns 1, and 3
writer = pd.ExcelWriter('output.xlsx', engine='xlsxwriter')
df.to_excel(writer) # index= False)
workbook = writer.book
ws = writer.sheets['Sheet1']
format1 = workbook.add_format({'num_format': '$#,##0.00'})
ws.set_column(1, 1, 18, format1)
ws.set_column(3, 3, 18, format1)
writer.save()
writer.close()
reference to documentation: https://xlsxwriter.readthedocs.io/example_pandas_column_formats.html

How can I leave every answer from 'for'

I think my code works well.
But the problem is that my code does not leave every answer on DataFrame R.
When I print R, only the last answer appeared.
What should I do to display every answer?
I want to add answer on the next column.
import numpy as np
import pandas as pd
DATA = pd.DataFrame()
DATA = pd.read_excel('C:\gskim\P4DS/Monthly Stock adjClose2.xlsx')
DATA = DATA.set_index("Date")
DATA1 = np.log(DATA/DATA.shift(1))
DATA2 = DATA1.drop(DATA1.index[0])*100
F = pd.DataFrame(index = DATA2.index)
for i in range (0, 276):
Q = DATA2.iloc[i].dropna()
W = sorted(abs(Q), reverse = False)
W_qcut = pd.qcut(W, 5, labels = ['A', 'B', 'C', 'D', 'E'])
F = Q.groupby(W_qcut).sum()
R = pd.DataFrame(F)
print(R)
the first table is the current result, I want to fill every blank tables on the second table as a result:

Is it possible to change a graphs x and y axis major/minor units using openpyxl?

I have tried the following but none work.
chart.auto_axis = False
chart.x_axis.unit = 365
chart.set_y_axis({'minor_unit': 100, 'major_unit':365})
changing the max and min scale for both axis is straight forward
chart.x_axis.scaling.min = 0
chart.x_axis.scaling.max = 2190
chart.y_axis.scaling.min = 0
chart.y_axis.scaling.max = 2
so I'm hoping there is a straight forward solution to this. Here is a mcve.
from openpyxl import load_workbook, Workbook
import datetime
from openpyxl.chart import ScatterChart, Reference, Series
wb = Workbook()
ws = wb.active
rows = [
['data point 1', 'data point2'],
[25, 1],
[100, 2],
[500, 3],
[800, 4],
[1200, 5],
[2100, 6],]
for row in rows:
ws.append(row)
chart = ScatterChart()
chart.title = "Example Chart"
chart.style = 18
chart.y_axis.title = 'y'
chart.x_axis.title = 'x'
chart.x_axis.scaling.min = 0
chart.y_axis.scaling.min = 0
chart.X_axis.scaling.max = 2190
chart.y_axis.scaling.max = 6
xvalues = Reference(ws, min_col=1, min_row=2, max_row=7)
yvalues = Reference(ws, min_col=2, min_row=2, max_row=7)
series = Series(values=yvalues, xvalues=xvalues, title="DP 1")
chart.series.append(series)
ws.add_chart(chart, "D2")
wb.save("chart.xlsx")
I need to automate changing the axis to units of 365 or what ever.
Very late answer, but I figured out how to do this just after finding this question.
You need to set the major unit axis to 365.25, and the format to show just the year:
chart.x_axis.number_format = 'yyyy'
chart.x_axis.majorUnit = 365.25

vb.net chart with week numbers as X Axis

I know a similar question was asked before, but it wasn't answered.
I have a chart where I use week numbers as its X-axis, that are retrieved as part of the SQL query.
It works fine up until a new year starts. In such a case, even though the weeks are ordered correctly when retrieved (for example, 49, 50, 51, 52, 1, 2, 3), they appear on the axis numerically ordered: 1, 2, 3, 49, 50, 51, 52.
Is there a way to fix that?
The relevant sql query part is:
SELECT DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time) week_num,
COUNT(*) num_sessions
FROM parking_log
GROUP BY DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time)
ORDER BY DATEPART(year, start_charge_time),
DATEPART(week, start_charge_time)
The Chart is:
Dim SeriesParkingRev As Series
SeriesParkingRev = ChartParkingSummery.Series("SeriesParkingRev")
' Set series chart type
SeriesParkingRev.ChartType = SeriesChartType.Line
SeriesParkingRev.MarkerStyle = MarkerStyle.Square
SeriesParkingRev.MarkerSize = 10
SeriesParkingRev.BorderWidth = 3
SeriesParkingRev.Color = Color.Red
SeriesParkingRev.IsValueShownAsLabel = True
SeriesParkingRev.IsVisibleInLegend = True
'' Set series members names for the X and Y values
SeriesParkingRev.XValueMember = "week_num"
SeriesParkingRev.YValueMembers = "total_charge"
SeriesParkingRev.LegendText = "Parking Revenue"
'' --------------------------
' Create the destination series and add it to the chart
'Dim SeriesParkingTime As New Series("SeriesParkingTime")
'ChartParkingSummery.Series.Add(SeriesParkingTime)
Dim SeriesParkingTime As Series
SeriesParkingTime = ChartParkingSummery.Series("SeriesParkingTime")
' Ensure the destination series is a Line or Spline chart type
SeriesParkingTime.ChartType = SeriesChartType.Line
SeriesParkingTime.MarkerStyle = MarkerStyle.Diamond
SeriesParkingTime.MarkerSize = 12
SeriesParkingTime.BorderWidth = 3
SeriesParkingTime.IsValueShownAsLabel = True
SeriesParkingTime.Color = Color.Blue
' Assign the series to the same chart area as the column chart
SeriesParkingTime.ChartArea = ChartParkingSummery.Series("SeriesParkingRev").ChartArea
' Assign this series to use the secondary axis and set its maximum to be 100%
SeriesParkingTime.YAxisType = AxisType.Secondary
ChartParkingSummery.Series("SeriesParkingTime").XValueMember = "week_num"
ChartParkingSummery.Series("SeriesParkingTime").YValueMembers = "avg_time"
ChartParkingSummery.Series("SeriesParkingTime").LegendText = "Average Time"
'' ----------------------------------------
'Dim SeriesCars As New Series("SeriesCars")
'ChartParkingSummery.Series.Add(SeriesCars)
Dim SeriesCars As Series
SeriesCars = ChartParkingSummery.Series("SeriesCars")
SeriesCars.ChartType = SeriesChartType.Point
SeriesCars.MarkerStyle = MarkerStyle.Triangle
SeriesCars.MarkerSize = 8
SeriesCars.BorderWidth = 3
SeriesCars.IsValueShownAsLabel = True
SeriesCars.MarkerStyle = MarkerStyle.Triangle
SeriesCars.MarkerSize = 15
SeriesCars.MarkerColor = Color.Green
ChartParkingSummery.Series("SeriesCars").XValueMember = "week_num"
ChartParkingSummery.Series("SeriesCars").YValueMembers = "num_cars"
ChartParkingSummery.Series("SeriesCars").LegendText = "Cars"
'' ----------------------------------------
ChartParkingSummery.Legends.Add(New Legend("Default"))
' Set legend style
ChartParkingSummery.Legends("Default").LegendStyle = LegendStyle.Table
' Set table style if legend style is Table
' Set legend docking
ChartParkingSummery.Legends("Default").Docking = Docking.Right
' Set legend alignment
ChartParkingSummery.Legends("Default").Alignment = StringAlignment.Center
ChartParkingSummery.Titles.Add("Revenue, Avg Time & Cars")